|
| 1 | +# Django Require 2FA |
| 2 | + |
| 3 | +A production-ready Django app that enforces Two-Factor Authentication (2FA) across your entire application. |
| 4 | + |
| 5 | +## Why This Exists |
| 6 | + |
| 7 | +### The Django-Allauth Gap |
| 8 | + |
| 9 | +Django-allauth provides excellent 2FA functionality, but **intentionally does not include** site-wide 2FA enforcement. This decision was made explicit in: |
| 10 | + |
| 11 | +- **[PR #3710](https://github.com/pennersr/django-allauth/pull/3710)** - A middleware approach was proposed but **rejected** by the maintainer |
| 12 | +- **[Issue #3649](https://github.com/pennersr/django-allauth/issues/3649)** - Community discussed various enforcement strategies, issue was **closed without implementation** |
| 13 | + |
| 14 | +The django-allauth maintainer's position: |
| 15 | +> "leave such functionality for individual projects to implement" |
| 16 | +
|
| 17 | +### The Enterprise Need |
| 18 | + |
| 19 | +Many organizations need to: |
| 20 | +- Enforce 2FA for **all users** (not optional) |
| 21 | +- Configure 2FA requirements **at runtime** (not hardcoded) |
| 22 | +- Support **SaaS/multi-tenant** scenarios with organization-level policies |
| 23 | +- Maintain **audit trails** of security configuration changes |
| 24 | + |
| 25 | +Since django-allauth won't provide this, there's a clear market need for a standalone solution. |
| 26 | + |
| 27 | +## Our Solution |
| 28 | + |
| 29 | +### What We Built |
| 30 | + |
| 31 | +This app provides what the **rejected django-allauth PR attempted**, but with significant improvements: |
| 32 | + |
| 33 | +| Feature | Rejected PR #3710 | Our Implementation | |
| 34 | +|---------|------------------|-------------------| |
| 35 | +| URL Matching | String prefix matching (vulnerable) | Proper Django URL resolution | |
| 36 | +| Configuration | Hardcoded settings | Runtime admin configuration | |
| 37 | +| Testing | Basic tests | 15 comprehensive security tests | |
| 38 | +| Security | Known vulnerabilities | Production-hardened | |
| 39 | +| Admin Protection | Exempt admin login | Proper 2FA for admin access | |
| 40 | + |
| 41 | +### Key Security Features |
| 42 | + |
| 43 | +- **Vulnerability Protection**: Fixed Issue #173 path traversal attacks |
| 44 | +- **URL Resolution**: Uses Django's proper URL resolution instead of dangerous string matching |
| 45 | +- **Configuration Validation**: Prevents dangerous Django settings misconfigurations |
| 46 | +- **Comprehensive Testing**: 15 security tests covering edge cases, malformed URLs, and regression scenarios |
| 47 | +- **Admin Security**: Removed admin login exemption (admins now require 2FA) |
| 48 | + |
| 49 | +### Architecture |
| 50 | + |
| 51 | +- **Django-Solo Pattern**: Runtime configuration via admin interface |
| 52 | +- **Middleware Approach**: Site-wide enforcement without code changes |
| 53 | +- **Allauth Integration**: Works seamlessly with django-allauth's MFA system |
| 54 | +- **Production Ready**: Data migrations, backward compatibility, zero downtime |
| 55 | + |
| 56 | +## Usage |
| 57 | + |
| 58 | +### Installation (Internal) |
| 59 | + |
| 60 | +1. Add to `INSTALLED_APPS`: |
| 61 | + ```python |
| 62 | + INSTALLED_APPS = [ |
| 63 | + # ... |
| 64 | + 'require2fa', |
| 65 | + # ... |
| 66 | + ] |
| 67 | + ``` |
| 68 | + |
| 69 | +2. Add to `MIDDLEWARE`: |
| 70 | + ```python |
| 71 | + MIDDLEWARE = [ |
| 72 | + # ... |
| 73 | + 'require2fa.middleware.Require2FAMiddleware', |
| 74 | + ] |
| 75 | + ``` |
| 76 | + |
| 77 | +3. Run migrations: |
| 78 | + ```bash |
| 79 | + python manage.py migrate require2fa |
| 80 | + ``` |
| 81 | + |
| 82 | +### Configuration |
| 83 | + |
| 84 | +Visit Django Admin → Two-Factor Authentication Configuration: |
| 85 | +- **Require Two-Factor Authentication**: Toggle 2FA enforcement site-wide |
| 86 | +- Changes take effect immediately (no restart required) |
| 87 | + |
| 88 | +### How It Works |
| 89 | + |
| 90 | +1. **Authenticated users** without 2FA are redirected to `/accounts/2fa/` |
| 91 | +2. **Exempt URLs** (login, logout, 2FA setup) remain accessible |
| 92 | +3. **Static/media files** are automatically detected and exempted |
| 93 | +4. **Admin access** requires 2FA verification (security improvement) |
| 94 | + |
| 95 | +## Testing |
| 96 | + |
| 97 | +Run the comprehensive test suite: |
| 98 | +```bash |
| 99 | +python manage.py test require2fa |
| 100 | +``` |
| 101 | + |
| 102 | +**15 security tests** covering: |
| 103 | +- URL resolution edge cases |
| 104 | +- Malformed URL handling |
| 105 | +- Static file exemptions |
| 106 | +- Admin protection |
| 107 | +- Configuration security |
| 108 | +- Regression tests for known vulnerabilities |
| 109 | + |
| 110 | +## Future: Package Extraction |
| 111 | + |
| 112 | +This app is designed to be **extracted into a standalone Django package**: |
| 113 | + |
| 114 | +### Target Package Structure |
| 115 | +``` |
| 116 | +django-require2fa/ |
| 117 | +├── pyproject.toml # Modern Python packaging |
| 118 | +├── README.md # Installation & usage docs |
| 119 | +├── LICENSE # Open source license |
| 120 | +├── CHANGELOG.md # Version history |
| 121 | +├── .github/workflows/ # CI/CD pipeline |
| 122 | +└── require2fa/ # This app (copy-paste ready) |
| 123 | +``` |
| 124 | + |
| 125 | +### Market Positioning |
| 126 | +- **Fills django-allauth gap**: Provides what they explicitly won't |
| 127 | +- **Enterprise-ready**: SaaS/multi-tenant 2FA enforcement |
| 128 | +- **Security-first**: Production-hardened with comprehensive testing |
| 129 | +- **Community need**: Addresses requests from Issues #3649 and PR #3710 |
| 130 | + |
| 131 | +## Contributing |
| 132 | + |
| 133 | +When making changes: |
| 134 | +1. **Security first** - any middleware changes need security review |
| 135 | +2. **Comprehensive testing** - maintain the 15-test security suite |
| 136 | +3. **Backward compatibility** - consider migration paths |
| 137 | +4. **Documentation** - update this README with architectural decisions |
| 138 | + |
| 139 | +## License |
| 140 | + |
| 141 | +MIT License - ready for open source packaging and community adoption. |
0 commit comments