Simple extension that provides Basic and Digest HTTP authentication for Flask routes
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Combines multiple authentication methods into a single handler, automatically selecting the appropriate authentication method based on request headers. MultiAuth enables flexible endpoint protection with fallback authentication schemes.
Creates a multi-authentication handler that combines different authentication methods.
class MultiAuth:
def __init__(self, main_auth, *args):
"""
Initialize multi-authentication handler.
Parameters:
- main_auth: Primary authentication method (used as fallback)
- *args: Additional authentication methods to support
Usage:
multi_auth = MultiAuth(basic_auth, token_auth, digest_auth)
"""Protect Flask routes with automatic authentication method selection.
def login_required(self, f=None, role=None, optional=None):
"""
Decorator to require authentication using any compatible method.
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
Usage:
@multi_auth.login_required
def flexible_endpoint():
return f"Hello {multi_auth.current_user()}"
@multi_auth.login_required(role='admin')
def admin_endpoint():
return "Admin access via any auth method"
"""Access current authenticated user information within protected routes.
def current_user(self):
"""
Get current authenticated user from whichever auth method was used.
Returns:
User object from the authentication method that handled the request
"""from flask import Flask
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
# Set up Basic authentication
basic_auth = HTTPBasicAuth()
users = {
"john": generate_password_hash("hello"),
"susan": generate_password_hash("bye")
}
@basic_auth.verify_password
def verify_password(username, password):
if username in users and check_password_hash(users.get(username), password):
return username
# Set up Token authentication
token_auth = HTTPTokenAuth('Bearer')
tokens = {
"secret-token-1": "john",
"secret-token-2": "susan"
}
@token_auth.verify_token
def verify_token(token):
return tokens.get(token)
# Combine authentication methods
multi_auth = MultiAuth(basic_auth, token_auth)
@app.route('/api/data')
@multi_auth.login_required
def get_data():
return {
"user": multi_auth.current_user(),
"data": "Available via Basic auth or Bearer token"
}
# Usage examples:
# curl -u john:hello http://localhost:5000/api/data
# curl -H "Authorization: Bearer secret-token-1" http://localhost:5000/api/datafrom flask import Flask
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, HTTPDigestAuth, MultiAuth
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
# Set up Basic authentication
basic_auth = HTTPBasicAuth()
@basic_auth.verify_password
def verify_basic_password(username, password):
users = {"john": "hello", "susan": "bye"}
if username in users and users[username] == password:
return username
# Set up Digest authentication
digest_auth = HTTPDigestAuth()
@digest_auth.get_password
def get_digest_password(username):
users = {"john": "hello", "susan": "bye"}
return users.get(username)
# Set up Token authentication
token_auth = HTTPTokenAuth('Bearer')
@token_auth.verify_token
def verify_token(token):
tokens = {"token123": "john", "token456": "susan"}
return tokens.get(token)
# Combine all three methods
multi_auth = MultiAuth(basic_auth, digest_auth, token_auth)
@app.route('/api/flexible')
@multi_auth.login_required
def flexible_endpoint():
return {
"message": f"Hello {multi_auth.current_user()}",
"auth_method": "Any of: Basic, Digest, or Bearer token"
}from flask import Flask
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
app = Flask(__name__)
# Set up authentication methods
basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth('Bearer')
# User database with roles
users = {
"john": {"password": "hello", "roles": ["user"]},
"susan": {"password": "bye", "roles": ["user", "admin"]},
"admin": {"password": "secret", "roles": ["admin"]}
}
tokens = {
"user-token": {"user": "john", "roles": ["user"]},
"admin-token": {"user": "susan", "roles": ["user", "admin"]}
}
@basic_auth.verify_password
def verify_password(username, password):
if username in users and users[username]["password"] == password:
return {"username": username, "roles": users[username]["roles"]}
@basic_auth.get_user_roles
def get_basic_user_roles(user):
return user["roles"]
@token_auth.verify_token
def verify_token(token):
if token in tokens:
return tokens[token]
@token_auth.get_user_roles
def get_token_user_roles(user):
return user["roles"]
# Combine with role support
multi_auth = MultiAuth(basic_auth, token_auth)
@app.route('/api/user')
@multi_auth.login_required(role='user')
def user_endpoint():
return {"message": f"User access: {multi_auth.current_user()}"}
@app.route('/api/admin')
@multi_auth.login_required(role='admin')
def admin_endpoint():
return {"message": f"Admin access: {multi_auth.current_user()}"}from flask import Flask
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth, MultiAuth
app = Flask(__name__)
# High-priority authentication (checked first)
api_key_auth = HTTPTokenAuth('ApiKey', header='X-API-Key')
@api_key_auth.verify_token
def verify_api_key(key):
if key == "premium-api-key":
return {"user": "premium_user", "tier": "premium"}
# Fallback authentication
basic_auth = HTTPBasicAuth()
@basic_auth.verify_password
def verify_password(username, password):
if username == "regular" and password == "user":
return {"user": "regular_user", "tier": "basic"}
# API key auth has priority over basic auth
multi_auth = MultiAuth(api_key_auth, basic_auth)
@app.route('/api/service')
@multi_auth.login_required
def service_endpoint():
user = multi_auth.current_user()
return {
"user": user["user"],
"tier": user["tier"],
"message": "Service accessed with priority auth selection"
}
# Usage:
# curl -H "X-API-Key: premium-api-key" http://localhost:5000/api/service (premium)
# curl -u regular:user http://localhost:5000/api/service (basic)MultiAuth automatically selects the appropriate authentication method based on request headers:
is_compatible_auth() methodThe selection order follows the constructor parameter order: MultiAuth(first_priority, second_priority, ...).
MultiAuth delegates error handling to the selected authentication method:
The error response format depends on which authentication method processed the request.
Install with Tessl CLI
npx tessl i tessl/pypi-flask-httpauth