Skip to main content

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 Admin → Two-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.

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)

Source distribution for django-allauth-require2fa 1.2.2
File Size Uploaded
django_allauth_require2fa-1.2.2.tar.gz 78.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-allauth-require2fa 1.2.2
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

1.2.2 This release

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page