Authentication Decorators¶
Authentication decorators provide route-level authentication and authorization controls. These decorators help ensure secure communication and proper authentication for sensitive endpoints.
HTTPS Enforcement¶
Force secure connections for specific routes:
. Basic HTTPS Requirement¶
from guard.decorators import SecurityDecorator
guard_deco = SecurityDecorator(config)
@app.post("/api/login")
@guard_deco.require_https()
def login(credentials: dict):
return {"token": "secure_jwt_token"}
. Combined with Global HTTPS¶
# Global HTTPS enforcement
config = SecurityConfig(enforce_https=True)
# Route-specific override (still enforced due to global setting)
@app.get("/api/public")
@guard_deco.require_https() # Explicit requirement
def public_endpoint():
return {"data": "definitely secure"}
. HTTPS for Sensitive Operations¶
@app.post("/api/payment")
@guard_deco.require_https()
def payment_endpoint(payment_data: dict):
return {"status": "payment processed securely"}
@app.post("/api/user/password")
@guard_deco.require_https()
def change_password(password_data: dict):
return {"status": "password updated"}
Authentication Requirements¶
Enforce different types of authentication:
. Bearer Token Authentication¶
@app.get("/api/profile")
@guard_deco.require_auth(type="bearer")
def user_profile():
return {"profile": "user data"}
. Multiple Authentication Types¶
@app.get("/api/admin")
@guard_deco.require_auth(type="bearer")
def admin_endpoint():
return {"admin": "data"}
@app.get("/api/service")
@guard_deco.require_auth(type="basic")
def service_endpoint():
return {"service": "data"}
. Combined HTTPS and Auth¶
@app.post("/api/secure-admin")
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
def secure_admin():
return {"data": "doubly secure"}
API Key Authentication¶
Require API keys for endpoint access:
. Basic API Key Requirement¶
@app.get("/api/key-protected")
@guard_deco.api_key_auth(header_name="X-API-Key")
def api_key_endpoint():
return {"data": "api key required"}
. Custom Header Names¶
@app.get("/api/custom-key")
@guard_deco.api_key_auth(header_name="X-Custom-Auth")
def custom_key_endpoint():
return {"data": "custom header auth"}
@app.get("/api/service-key")
@guard_deco.api_key_auth(header_name="Authorization-Key")
def service_key_endpoint():
return {"data": "service authentication"}
. Multiple Key Requirements¶
@app.get("/api/dual-auth")
@guard_deco.api_key_auth(header_name="X-API-Key")
@guard_deco.api_key_auth(header_name="X-Service-Key")
def dual_auth_endpoint():
return {"data": "dual key authentication"}
Required Headers¶
Enforce specific headers for authentication and security:
. Security Headers¶
@app.get("/api/secure")
@guard_deco.require_headers({
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": "required"
})
def secure_endpoint():
return {"data": "csrf protected"}
. API Versioning Headers¶
@app.get("/api/v2/data")
@guard_deco.require_headers({
"Accept": "application/vnd.api+json",
"API-Version": "2.0"
})
def versioned_endpoint():
return {"data": "version 2.0", "format": "json-api"}
. Client Identification¶
@app.get("/api/client-specific")
@guard_deco.require_headers({
"X-Client-ID": "required",
"X-Client-Version": "required",
"User-Agent": "required"
})
def client_endpoint():
return {"data": "client identified"}
Combined Authentication Patterns¶
Stack multiple authentication decorators for comprehensive security:
. Maximum Security Endpoint¶
@app.post("/api/admin/critical")
@guard_deco.require_https() # Secure connection
@guard_deco.require_auth(type="bearer") # Bearer token
@guard_deco.api_key_auth(header_name="X-Admin-Key") # Admin API key
@guard_deco.require_headers({
"X-CSRF-Token": "required", # CSRF protection
"X-Request-ID": "required" # Request tracking
})
def critical_admin_endpoint():
return {"status": "critical operation completed"}
. Service-to-Service Authentication¶
@app.post("/api/service/webhook")
@guard_deco.require_https()
@guard_deco.api_key_auth(header_name="X-Service-Key")
@guard_deco.require_headers({
"X-Signature": "required", # Webhook signature
"Content-Type": "application/json"
})
def webhook_endpoint():
return {"status": "webhook processed"}
. Client Application Authentication¶
@app.get("/api/mobile/data")
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
@guard_deco.require_headers({
"X-App-Version": "required",
"X-Device-ID": "required",
"Accept": "application/json"
})
def mobile_endpoint():
return {"data": "mobile app data"}
Authentication Flow Examples¶
. Login Endpoint¶
@app.post("/auth/login")
@guard_deco.require_https()
@guard_deco.require_headers({
"Content-Type": "application/json",
"X-CSRF-Token": "required"
})
def login(credentials: dict):
# Validate credentials
return {"token": "jwt_token", "expires": "3600"}
. Token Refresh¶
@app.post("/auth/refresh")
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
@guard_deco.require_headers({
"X-Refresh-Token": "required"
})
def refresh_token():
return {"token": "new_jwt_token", "expires": "3600"}
. Logout¶
@app.post("/auth/logout")
@guard_deco.require_auth(type="bearer")
@guard_deco.require_headers({
"X-CSRF-Token": "required"
})
def logout():
return {"status": "logged out"}
API Gateway Pattern¶
Different authentication for different API tiers:
. Public API¶
@app.get("/api/public/status")
@guard_deco.api_key_auth(header_name="X-Public-Key")
def public_status():
return {"status": "public api active"}
. Partner API¶
@app.get("/api/partner/data")
@guard_deco.require_https()
@guard_deco.api_key_auth(header_name="X-Partner-Key")
@guard_deco.require_headers({
"X-Partner-ID": "required"
})
def partner_data():
return {"data": "partner exclusive"}
. Internal API¶
@app.get("/api/internal/admin")
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
@guard_deco.api_key_auth(header_name="X-Internal-Key")
@guard_deco.require_headers({
"X-Service-Name": "required",
"X-Request-Context": "required"
})
def internal_admin():
return {"data": "internal admin access"}
Error Handling¶
Authentication decorators return specific HTTP status codes:
- 400 Bad Request: Missing required headers
- 401 Unauthorized: Invalid or missing authentication
- 403 Forbidden: Valid auth but insufficient permissions
- 301/302 Redirect: HTTP to HTTPS redirect
. Custom Error Responses¶
config = SecurityConfig(
custom_error_responses={
400: "Missing required authentication headers",
401: "Invalid authentication credentials",
403: "Insufficient privileges for this operation"
}
)
Best Practices¶
. Layer Authentication Methods¶
Use multiple authentication factors for sensitive operations:
# Good: Multiple authentication layers
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
@guard_deco.api_key_auth(header_name="X-API-Key")
# Avoid: Single authentication method for sensitive data
# @guard_deco.api_key_auth(header_name="X-API-Key") # Too weak for sensitive ops
. Always Use HTTPS for Authentication¶
Never transmit credentials over unencrypted connections:
# Good: HTTPS enforced for login
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
# Bad: Authentication without HTTPS
# @guard_deco.require_auth(type="bearer") # Credentials could be intercepted
. Validate Header Content¶
Don't just check for presence, validate the content:
# The middleware handles presence validation
@guard_deco.require_headers({"X-API-Key": "required"})
# Your application code should validate the actual key value
def validate_api_key(request):
api_key = request.headers.get("X-API-Key")
return api_key in valid_keys
. Use Appropriate Authentication for Each Endpoint¶
Match authentication strength to data sensitivity:
# Public data: Light authentication
@guard_deco.api_key_auth(header_name="X-Public-Key")
# User data: Medium authentication
@guard_deco.require_auth(type="bearer")
# Admin data: Heavy authentication
@guard_deco.require_https()
@guard_deco.require_auth(type="bearer")
@guard_deco.api_key_auth(header_name="X-Admin-Key")
Integration with FastAPI Security¶
Combine decorators with FastAPI's built-in security:
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer
security = HTTPBearer()
@app.get("/api/integrated")
@guard_deco.require_https()
@guard_deco.require_headers({"X-Client-ID": "required"})
def integrated_endpoint(token: str = Depends(security)):
# FastAPI handles token extraction
# Decorators handle additional security
return {"data": "integrated security"}
Testing Authentication¶
Test your authentication decorators:
import pytest
from fastapi.testclient import TestClient
def test_https_required():
# Should redirect HTTP to HTTPS
response = client.get("/api/secure", base_url="http://testserver")
assert response.status_code == 301
def test_api_key_required():
# Should reject without API key
response = client.get("/api/key-protected")
assert response.status_code == 400
# Should accept with valid API key
response = client.get(
"/api/key-protected",
headers={"X-API-Key": "valid-key"}
)
assert response.status_code == 200
Next Steps¶
Now that you understand authentication decorators, explore other security features:
- Access Control Decorators - IP and geographic restrictions
- Rate Limiting Decorators - Request rate controls
- Behavioral Analysis - Monitor authentication patterns
- Content Filtering - Request validation
For complete API reference, see the Authentication API Documentation.