Skip to main content

Site-wide Two-Factor Authentication enforcement middleware for Django applications using django-allauth

Project description

Django Require 2FA

PyPI version Test codecov Python versions Django versions

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

  1. Add require2fa to your INSTALLED_APPS:
INSTALLED_APPS = [
    # ...
    'django.contrib.admin',
    'allauth',
    'allauth.account',
    'allauth.mfa',
    'solo',
    'require2fa',  # Add this
    # ...
]
  1. Add the middleware to your MIDDLEWARE setting:
MIDDLEWARE = [
    # ... other middleware
    'require2fa.middleware.Require2FAMiddleware',  # Add this
]
  1. Run migrations:
python manage.py migrate require2fa
  1. Configure in Django Admin:
    • Go to Django AdminTwo-Factor Authentication Configuration
    • Check "Require Two-Factor Authentication"
    • Changes take effect immediately (no restart required)

How It Works

  1. Authenticated users without 2FA are redirected to /accounts/2fa/
  2. Exempt URLs (login, logout, 2FA setup) remain accessible
  3. Static/media files are automatically detected and exempted
  4. 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:

  1. Path Traversal Protection: Fixed vulnerability where /accounts/../admin/ could bypass 2FA
  2. URL Resolution: Uses Django's URL dispatcher, not string matching
  3. Configuration Validation: Prevents dangerous Django settings that would bypass security
  4. Comprehensive Testing: 15 security-focused tests ensure no regressions
  5. Security Logging: Uses dedicated security.2fa logger for audit trails

Contributing

Contributions are welcome! Please ensure:

  1. Security first - any middleware changes need security review
  2. Comprehensive testing - maintain the 15-test security suite
  3. Backward compatibility - consider migration paths
  4. 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_allauth_require2fa-1.1.0.tar.gz (65.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_allauth_require2fa-1.1.0-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file django_allauth_require2fa-1.1.0.tar.gz.

File metadata

File hashes

Hashes for django_allauth_require2fa-1.1.0.tar.gz
Algorithm Hash digest
SHA256 982235b097cc2d65bc26a59f3f216313d65c7c9dd15f7b304384c1a935246872
MD5 05a5797069f711b5ce61f5670114ba14
BLAKE2b-256 482ce98540ea82b3c38abbfbb83fc82576e4ffb716d41b72bea23bacccbfff01

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_allauth_require2fa-1.1.0.tar.gz:

Publisher: semantic-release.yml on heysamtexas/django-allauth-require2fa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_allauth_require2fa-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_allauth_require2fa-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c0b2aaab0e688be00b33cb9242bb035b00f5bd962baa47be515b9307cfe27f4c
MD5 ea66e703b954c89ebd2588291234b3b5
BLAKE2b-256 0f5f67cc53627f10448f31ca871f1429f2ac84e8e7bc61bdf46e296d2c7ea213

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_allauth_require2fa-1.1.0-py3-none-any.whl:

Publisher: semantic-release.yml on heysamtexas/django-allauth-require2fa

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page