Django Require 2FA
A production-ready Django package that enforces Two-Factor Authentication (2FA) across your entire application.
Why This Exists
The Django-Allauth Gap
Django-allauth provides excellent 2FA functionality, but intentionally does not include site-wide 2FA enforcement. This decision was made explicit in:
- PR #3710 - A middleware approach was proposed but rejected by the maintainer
- Issue #3649 - Community discussed various enforcement strategies, issue was closed without implementation
The django-allauth maintainer's position:
"leave such functionality for individual projects to implement"
The Enterprise Need
Many organizations need to:
- Enforce 2FA for all users (not optional)
- Configure 2FA requirements at runtime (not hardcoded)
- Support SaaS/multi-tenant scenarios with organization-level policies
- Maintain audit trails of security configuration changes
Since django-allauth won't provide this, there's a clear market need for a standalone solution.
Our Solution
What We Built
This package provides what the rejected django-allauth PR attempted, but with significant improvements:
| Feature | Rejected PR #3710 | Our Implementation |
|---|---|---|
| URL Matching | String prefix matching (vulnerable) | Proper Django URL resolution |
| Configuration | Hardcoded settings | Runtime admin configuration |
| Testing | Basic tests | 15 comprehensive security tests |
| Security | Known vulnerabilities | Production-hardened |
| Admin Protection | Exempt admin login | Proper 2FA for admin access |
Key Security Features
- Vulnerability Protection: Fixed Issue #173 path traversal attacks
- URL Resolution: Uses Django's proper URL resolution instead of dangerous string matching
- Configuration Validation: Prevents dangerous Django settings misconfigurations
- Comprehensive Testing: 15 security tests covering edge cases, malformed URLs, and regression scenarios
- Admin Security: Removed admin login exemption (admins now require 2FA)
Installation
Install from PyPI:
pip install django-allauth-require2fa
Or with uv (recommended):
uv add django-allauth-require2fa
Quick Start
- Add
require2fato yourINSTALLED_APPS:
INSTALLED_APPS = [
# ...
'django.contrib.admin',
'allauth',
'allauth.account',
'allauth.mfa',
'solo',
'require2fa', # Add this
# ...
]
- Add the middleware to your
MIDDLEWAREsetting:
MIDDLEWARE = [
# ... other middleware
'require2fa.middleware.Require2FAMiddleware', # Add this
]
- Run migrations:
python manage.py migrate require2fa
- Configure in Django Admin:
- Go to Django Admin → Two-Factor Authentication Configuration
- Check "Require Two-Factor Authentication"
- Changes take effect immediately (no restart required)
How It Works
- Authenticated users without 2FA are redirected to
/accounts/2fa/ - Exempt URLs (login, logout, 2FA setup) remain accessible
- Static/media files are automatically detected and exempted
- Admin access requires 2FA verification (security improvement)
Configuration
Runtime Configuration
Visit Django Admin → Two-Factor Authentication Configuration:
- Require Two-Factor Authentication: Toggle 2FA enforcement site-wide
- Changes take effect immediately (no server restart required)
Architecture
- Django-Solo Pattern: Runtime configuration via admin interface
- Middleware Approach: Site-wide enforcement without code changes
- Allauth Integration: Works seamlessly with django-allauth's MFA system
- Production Ready: Data migrations, backward compatibility, zero downtime
Requirements
- Python: 3.12+
- Django: 4.2+
- django-allauth: 0.57.0+
- django-solo: 2.0.0+
Testing
This package includes 15 comprehensive security tests covering:
- URL resolution edge cases
- Malformed URL handling
- Static file exemptions
- Admin protection
- Configuration security
- Regression tests for known vulnerabilities
# Run tests (standalone package)
python -m django test require2fa.tests --settings=require2fa.tests.settings
# Or in a Django project (after installation)
python manage.py test require2fa
Security
This middleware is security-critical. Key protections include:
- Path Traversal Protection: Fixed vulnerability where
/accounts/../admin/could bypass 2FA - URL Resolution: Uses Django's URL dispatcher, not string matching
- Configuration Validation: Prevents dangerous Django settings that would bypass security
- Comprehensive Testing: 15 security-focused tests ensure no regressions
- Security Logging: Uses dedicated
security.2falogger for audit trails
Contributing
Contributions are welcome! Please ensure:
- Security first - any middleware changes need security review
- Comprehensive testing - maintain the 15-test security suite
- Backward compatibility - consider migration paths
- Code quality - use pre-commit hooks (
pre-commit install)
Development Setup
# Clone the repository
git clone https://github.com/heysamtexas/django-allauth-require2fa.git
cd django-allauth-require2fa
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Set up development environment (one command!)
make dev-setup
# Run tests to verify setup
make test
Development Commands
The project uses a Makefile for convenient development tasks:
# Testing and Quality
make test # Run Django tests
make quality # Run all code quality checks (format, lint, security, mypy)
make all # Full workflow (install + quality + test)
# Individual Quality Checks
make format # Auto-format code with ruff
make lint # Check code style with ruff
make security # Run security scan with bandit
make mypy # Run type checking
# Development Utilities
make clean # Clean up generated files
make help # Show all available commands
Manual Commands (Alternative)
If you prefer running commands directly:
# Install and setup
uv sync --dev
uv run pre-commit install
# Testing
uv run python -m django test require2fa.tests --settings=require2fa.tests.settings
# Code quality
uv run ruff format .
uv run ruff check .
uv run bandit -r require2fa/
uv run mypy require2fa/
License
MIT License - see LICENSE file for details.
Changelog
See CHANGELOG.md for version history.
Note: This package fills the gap left by django-allauth's intentional decision not to include site-wide 2FA enforcement. It provides enterprise-ready security features that many organizations require.
Metadata
Release files for django-allauth-require2fa 1.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_allauth_require2fa-1.2.2.tar.gz | 78.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_allauth_require2fa-1.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.1 kB
Release files / django_allauth_require2fa-1.2.2.tar.gz
| Download URL | django_allauth_require2fa-1.2.2.tar.gz |
|---|---|
| Size | 78.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4500c070ac63a92d85c64fab9320cd9a3037295d98ddf92e18de252431c47a66
|
|
BLAKE2b-256 checksum How to use checksums |
451eb87f3f864849676e127a854c42f9d69bddea16a1119535772ed5836e5ad5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2025.
Transparency logRelease files / django_allauth_require2fa-1.2.2-py3-none-any.whl
| Download URL | django_allauth_require2fa-1.2.2-py3-none-any.whl |
|---|---|
| Size | 17.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e99f6cbff0425db6ac7682ae52ae8b0b80b65f2ad299cd4aa648e3f66951284d
|
|
BLAKE2b-256 checksum How to use checksums |
c2b1c6e43c9a4b5d55b9b2b27b9332d706f92e98d5cc9bbf5dcdfaad3c09a9ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2025.
Transparency log