CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flask-httpauth

Simple extension that provides Basic and Digest HTTP authentication for Flask routes

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

digest-auth.mddocs/

Digest Authentication

HTTP Digest authentication implementation providing enhanced security over Basic auth through challenge-response mechanisms. Digest auth never transmits passwords in clear text, instead using MD5 hashing with nonce values to prevent replay attacks.

Capabilities

HTTPDigestAuth Class

Creates an HTTP Digest authentication handler with configurable algorithms, quality of protection, and nonce/opaque value management.

class HTTPDigestAuth(HTTPAuth):
    def __init__(self, scheme=None, realm=None, use_ha1_pw=False, qop='auth', algorithm='MD5'):
        """
        Initialize Digest authentication handler.
        
        Parameters:
        - scheme (str, optional): Authentication scheme, defaults to 'Digest'
        - realm (str, optional): Authentication realm, defaults to 'Authentication Required'
        - use_ha1_pw (bool): Use HA1 hashed passwords instead of plain passwords
        - qop (str|list): Quality of protection ('auth' or list of QOP values)
        - algorithm (str): Hash algorithm ('MD5' or 'MD5-Sess')
        """

Nonce Management

Configure nonce generation and verification for preventing replay attacks.

def generate_nonce(self, f):
    """
    Decorator to register nonce generation callback.
    
    Parameters:
    - f (function): Callback function() -> nonce_string
    
    Returns:
    The decorated function
    
    Usage:
    @auth.generate_nonce
    def generate_nonce():
        return secrets.token_hex(16)
    """

def verify_nonce(self, f):
    """
    Decorator to register nonce verification callback.
    
    Parameters:
    - f (function): Callback function(nonce) -> bool
    
    Returns:
    The decorated function
    
    Usage:
    @auth.verify_nonce
    def verify_nonce(nonce):
        return nonce in valid_nonces
    """

def get_nonce(self):
    """
    Generate a new nonce value.
    
    Returns:
    str: Generated nonce string
    """

Opaque Value Management

Configure opaque value generation and verification for additional security.

def generate_opaque(self, f):
    """
    Decorator to register opaque value generation callback.
    
    Parameters:
    - f (function): Callback function() -> opaque_string
    
    Returns:
    The decorated function
    """

def verify_opaque(self, f):
    """
    Decorator to register opaque value verification callback.
    
    Parameters:
    - f (function): Callback function(opaque) -> bool
    
    Returns:
    The decorated function
    """

def get_opaque(self):
    """
    Generate a new opaque value.
    
    Returns:
    str: Generated opaque string
    """

Password and Hash Management

Handle password retrieval and HA1 hash generation for digest authentication.

def generate_ha1(self, username, password):
    """
    Generate HA1 hash for digest authentication.
    
    Parameters:
    - username (str): Username
    - password (str): Plain text password
    
    Returns:
    str: MD5 hash of username:realm:password
    """

Route Protection

Protect Flask routes with Digest authentication using the login_required decorator.

def login_required(self, f=None, role=None, optional=None):
    """
    Decorator to require digest authentication for Flask routes.
    
    Parameters:
    - f (function, optional): Flask route function to protect
    - role (str|list, optional): Required user role(s)
    - optional (bool, optional): Make authentication optional
    
    Returns:
    Decorated function or decorator
    """

Authentication Header Generation

Generate proper WWW-Authenticate headers for digest authentication challenges.

def authenticate_header(self):
    """
    Generate WWW-Authenticate header for digest authentication.
    
    Returns:
    str: Properly formatted digest authentication challenge header
    """

Usage Examples

Basic Digest Authentication

from flask import Flask
from flask_httpauth import HTTPDigestAuth

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()

users = {
    "john": "hello",
    "susan": "bye"
}

@auth.get_password
def get_pw(username):
    if username in users:
        return users.get(username)
    return None

@app.route('/')
@auth.login_required
def index():
    return f"Hello, {auth.username()}"

if __name__ == '__main__':
    app.run()

Custom Nonce Generation

from flask import Flask, session
from flask_httpauth import HTTPDigestAuth
import secrets
import time

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()

# Store nonces with timestamps
nonces = {}

@auth.generate_nonce
def generate_nonce():
    nonce = secrets.token_hex(16)
    nonces[nonce] = time.time()
    return nonce

@auth.verify_nonce
def verify_nonce(nonce):
    if nonce in nonces:
        # Check if nonce is still valid (not expired)
        if time.time() - nonces[nonce] < 300:  # 5 minutes
            return True
        else:
            del nonces[nonce]
    return False

HA1 Password Mode

from flask import Flask
from flask_httpauth import HTTPDigestAuth

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth(use_ha1_pw=True)

# Pre-computed HA1 hashes: MD5(username:realm:password)
users_ha1 = {
    "john": "b4bbcabacfa91dcc1f5e1e47e3e6bdbe",  # john:Authentication Required:hello
    "susan": "1f3870be274f6c49b3e31a0c6728957f"  # susan:Authentication Required:bye
}

@auth.get_password
def get_password_ha1(username):
    if username in users_ha1:
        return users_ha1[username]
    return None

@app.route('/')
@auth.login_required
def index():
    return f"Hello, {auth.username()}"

Custom QOP and Algorithm

from flask import Flask
from flask_httpauth import HTTPDigestAuth

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'

# Configure digest auth with MD5-Sess algorithm
auth = HTTPDigestAuth(qop=['auth', 'auth-int'], algorithm='MD5-Sess')

users = {
    "john": "hello",
    "susan": "bye"
}

@auth.get_password
def get_pw(username):
    return users.get(username)

@app.route('/')
@auth.login_required
def index():
    return f"Hello, {auth.username()}"

Error Handling

Digest authentication handles various error conditions:

  • 401 Unauthorized: Invalid credentials, expired nonce, or missing authentication
  • 403 Forbidden: Valid credentials but insufficient role permissions
  • Automatic Challenge: WWW-Authenticate header with digest parameters
  • Nonce Validation: Automatic nonce expiration and replay prevention
  • Opaque Validation: Server-side opaque value verification

The digest implementation automatically manages the challenge-response cycle and validates all digest authentication parameters according to RFC 2617 specifications.

Install with Tessl CLI

npx tessl i tessl/pypi-flask-httpauth

docs

basic-auth.md

digest-auth.md

index.md

multi-auth.md

roles.md

token-auth.md

tile.json