Name | fastsecure JSON |
Version |
0.3.0
JSON |
| download |
home_page | None |
Summary | Flexible authentication system for FastAPI applications |
upload_time | 2025-02-11 22:30:32 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.9 |
license | None |
keywords |
fastapi
authentication
oauth
jwt
session
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# FastSecure
<p align="center">
<a href="https://igorbenav.github.io/fastsecure/">
<img src="docs/assets/FastSecure.png" alt="FastSecure logo" width="65%" height="auto">
</a>
</p>
A modern, flexible authentication system for FastAPI applications with support for multiple authentication methods and strategies.
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Core Concepts](#core-concepts)
- [Basic Usage Guide](#basic-usage-guide)
- [Setting Up JWT Authentication](#setting-up-jwt-authentication)
- [Setting Up Session Authentication](#setting-up-session-authentication)
- [Setting Up OAuth Authentication](#setting-up-oauth-authentication)
- [Advanced Usage Guide](#advanced-usage-guide)
- [Combining Authentication Methods](#combining-authentication-methods)
- [Custom Authentication Providers](#custom-authentication-providers)
- [Storage Backends](#storage-backends)
- [Security Best Practices](#security-best-practices)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
> [!WARNING]
> FastSecure is still experimental.
## Features
- 🔐 **Multiple Authentication Methods**
- JWT tokens with refresh token support and flexible configuration
- Session-based authentication with configurable storage backends
- OAuth 2.0 providers (Google, GitHub) with standardized user info
- Easy to extend with custom authentication providers
- 🔄 **Flexible Authentication Strategies**
- Use single or multiple authentication methods
- Support for AND logic (require all methods)
- Support for OR logic (allow any method)
- Optional authentication methods
- Path-based authentication requirements
- 🗄️ **Session Storage Options**
- In-memory storage for development
- Redis backend for distributed systems
- Database backend (SQLAlchemy) for persistence
- Easy to implement custom storage backends
- 🛡️ **Security Features**
- Token expiration and refresh
- Session timeout and cleanup
- Concurrent session limits
- Scope-based authorization
- IP tracking and user agent logging
## Installation
1. Install using pip:
```bash
pip install fastsecure
```
2. Install using uv or poetry:
```bash
uv add fastsecure
```
```bash
poetry add fastsecure
```
## Core Concepts
Before diving into the implementation, let's understand the core concepts:
### Authentication Manager
The `AuthenticationManager` is the central component that:
- Manages authentication providers
- Handles authentication strategies
- Enforces authentication requirements
- Coordinates the authentication flow
### Authentication Providers
Providers implement specific authentication methods:
- JWT tokens
- Sessions
- OAuth
- Custom methods
### Authentication Strategies
Strategies determine how multiple authentication methods are combined:
- `AuthStrategy.ANY`: Any provider can authenticate (OR logic)
- `AuthStrategy.ALL`: All providers must authenticate (AND logic)
### Authentication Requirements
Requirements specify which authentication methods are needed for specific paths:
- Required providers
- Optional providers
- Authentication strategy
- Required scopes
## Basic Usage Guide
### Setting Up JWT Authentication
1. **Create a Basic FastAPI Application**
```python
from fastapi import FastAPI, Depends, HTTPException
from fastsecure import AuthenticationManager, JWTAuthenticationProvider
app = FastAPI()
```
2. **Initialize Authentication Manager and JWT Provider**
```python
# Initialize authentication
auth_manager = AuthenticationManager()
# Configure JWT provider
jwt_auth = JWTAuthenticationProvider(
secret_key="your-secret-key", # Use a secure key in production!
access_token_expire_minutes=30,
refresh_token_expire_days=7
)
# Register the provider
auth_manager.register_provider("jwt", jwt_auth)
```
3. **Create Authentication Dependency**
```python
from fastapi import Request
from typing import Optional
async def requires_auth(request: Request, path: Optional[str] = None) -> dict:
"""
FastAPI dependency for authentication requirements.
Args:
request: The FastAPI request object
path: Optional path override for authentication requirements
Returns:
Authentication result if successful
Raises:
HTTPException: If authentication fails
"""
# Get authentication data from request headers
auth_header = request.headers.get("Authorization")
if not auth_header:
raise HTTPException(status_code=401, detail="No authentication provided")
# Parse Bearer token
try:
scheme, token = auth_header.split()
if scheme.lower() != "bearer":
raise HTTPException(status_code=401, detail="Invalid authentication scheme")
except ValueError:
raise HTTPException(status_code=401, detail="Invalid authorization header")
# Authenticate using the manager
result = await auth_manager.authenticate(
path or request.url.path,
{"jwt": {"access_token": token}}
)
if not result.success:
raise HTTPException(
status_code=401,
detail="Authentication failed",
headers={"WWW-Authenticate": "Bearer"}
)
return result
```
4. **Configure Protected Routes**
```python
# Add authentication requirement for protected paths
auth_manager.add_requirement(
"/api/protected/*", # Path pattern
providers=["jwt"], # Required providers
scopes=["read"] # Required scopes (optional)
)
```
5. **Implement Login and Protected Routes**
```python
from pydantic import BaseModel
class LoginCredentials(BaseModel):
username: str
password: str
@app.post("/api/auth/login")
async def login(credentials: LoginCredentials):
# Validate credentials (implement your own validation)
user_id = validate_credentials(credentials)
# Authenticate with JWT provider
result = await auth_manager.authenticate(
"/api/protected/data",
{"jwt": {
"user_id": user_id,
"scopes": ["read", "write"]
}}
)
if not result.success:
raise HTTPException(401, "Authentication failed")
return {
"access_token": result.access_token,
"refresh_token": result.refresh_token,
"token_type": "Bearer",
"expires_at": result.expires_at
}
@app.get("/api/protected/data")
async def protected_data(auth = Depends(requires_auth)):
return {
"message": "Authenticated!",
"user_id": auth.user_id,
"scopes": auth.metadata.get("scopes", [])
}
```
### Setting Up Session Authentication
1. **Choose a Storage Backend**
```python
from fastsecure import (
SessionAuthenticationProvider,
RedisSessionStore,
DatabaseSessionStore
)
# For development (in-memory)
session_auth = SessionAuthenticationProvider()
# For production with Redis
session_auth = SessionAuthenticationProvider(
session_store=RedisSessionStore("redis://localhost"),
session_timeout_minutes=60,
max_sessions_per_user=3,
cleanup_expired=True
)
```
2. **Configure Session Authentication**
```python
# Register the provider
auth_manager.register_provider("session", session_auth)
# Add requirements
auth_manager.add_requirement(
"/api/user/*",
providers=["session"]
)
```
3. **Implement Session Login**
```python
@app.post("/api/auth/session/login")
async def session_login(
credentials: LoginCredentials,
request: Request
):
user_id = validate_credentials(credentials)
result = await auth_manager.authenticate(
"/api/user/profile",
{"session": {
"user_id": user_id,
"ip_address": request.client.host,
"user_agent": request.headers.get("user-agent"),
"scopes": ["user:read"]
}}
)
if not result.success:
raise HTTPException(401, "Authentication failed")
response = JSONResponse({
"message": "Logged in successfully",
"user_id": user_id
})
# Set session cookie
response.set_cookie(
"session_id",
result.session_id,
httponly=True,
secure=True,
samesite="lax",
expires=result.expires_at
)
return response
```
### Setting Up OAuth Authentication
1. **Configure OAuth Providers**
```python
from fastsecure import GoogleAuthProvider, GitHubAuthProvider
# Google Sign-In
google_auth = GoogleAuthProvider(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="http://localhost:8000/auth/google/callback"
)
# GitHub Sign-In
github_auth = GitHubAuthProvider(
client_id="your-client-id",
client_secret="your-client-secret",
redirect_uri="http://localhost:8000/auth/github/callback"
)
# Register providers
auth_manager.register_provider("google", google_auth)
auth_manager.register_provider("github", github_auth)
```
2. **Implement OAuth Flow**
```python
@app.get("/auth/google/login")
async def google_login():
authorization_url = google_auth.get_authorization_url(
state="random-secure-state" # Implement secure state handling
)
return RedirectResponse(authorization_url)
@app.get("/auth/google/callback")
async def google_callback(code: str, state: str):
# Validate state
validate_oauth_state(state)
result = await auth_manager.authenticate(
"/api/user/profile",
{"google": {"code": code}}
)
if not result.success:
raise HTTPException(401, "Authentication failed")
# Get user info from result
user_info = result.metadata["user_info"]
return {
"message": "Logged in with Google",
"email": user_info["email"],
"name": user_info["name"],
"access_token": result.access_token
}
```
## Advanced Usage Guide
### Combining Authentication Methods
1. **Require Multiple Methods (AND Strategy)**
```python
# Require both JWT and session authentication
auth_manager.add_requirement(
"/api/admin/*",
providers=["jwt", "session"],
strategy=AuthStrategy.ALL,
scopes=["admin"]
)
# Example request handler
@app.post("/api/admin/action")
async def admin_action(auth = Depends(auth_manager.requires_auth)):
if "admin" not in auth.metadata.get("scopes", []):
raise HTTPException(403, "Insufficient permissions")
return {"message": "Admin action successful"}
```
2. **Allow Alternative Methods (OR Strategy)**
```python
# Allow any authentication method
auth_manager.add_requirement(
"/api/user/*",
providers=["jwt", "session", "google"],
strategy=AuthStrategy.ANY
)
```
3. **Optional Authentication**
```python
# Add optional authentication methods
auth_manager.add_requirement(
"/api/public/*",
providers=["jwt"],
optional_providers=["session", "google"]
)
```
### Custom Authentication Providers
1. **Create a Custom Provider**
```python
from fastsecure import AuthenticationProvider, AuthenticationResult
from typing import Dict, Any, Set
class APIKeyAuthProvider(AuthenticationProvider):
def __init__(self, api_keys: Dict[str, str]):
self.api_keys = api_keys
def get_required_credentials(self) -> Set[str]:
return {"api_key"}
async def authenticate(
self,
credentials: Dict[str, Any]
) -> AuthenticationResult:
api_key = credentials.get("api_key")
if api_key not in self.api_keys:
return AuthenticationResult(
success=False,
provider=self.provider_name,
metadata={"error": "Invalid API key"}
)
return AuthenticationResult(
success=True,
provider=self.provider_name,
user_id=self.api_keys[api_key],
metadata={"api_key": api_key}
)
async def validate_authentication(
self,
auth_data: Dict[str, Any]
) -> bool:
return auth_data.get("api_key") in self.api_keys
```
2. **Register and Use Custom Provider**
```python
# Initialize with API keys
api_key_auth = APIKeyAuthProvider({
"key1": "user1",
"key2": "user2"
})
# Register provider
auth_manager.register_provider("apikey", api_key_auth)
# Add requirement
auth_manager.add_requirement(
"/api/service/*",
providers=["apikey"]
)
```
### Storage Backends
1. **Implement Custom Session Storage**
```python
from fastsecure import SessionStore
from typing import Dict, Any, List, Optional
from datetime import datetime
class CustomSessionStore(SessionStore):
async def create_session(
self,
user_id: int,
session_id: str,
expires_at: datetime,
metadata: Dict[str, Any]
) -> bool:
# Implement session creation
pass
async def get_session(
self,
session_id: str
) -> Optional[Dict[str, Any]]:
# Implement session retrieval
pass
async def update_session(
self,
session_id: str,
metadata: Dict[str, Any]
) -> bool:
# Implement session update
pass
async def delete_session(
self,
session_id: str
) -> bool:
# Implement session deletion
pass
async def get_user_sessions(
self,
user_id: int
) -> List[Dict[str, Any]]:
# Implement user sessions retrieval
pass
```
## Security Best Practices
1. **JWT Security**
- Use strong secret keys
- Set appropriate token expiration times
- Implement token refresh securely
- Use HTTPS for token transmission
2. **Session Security**
- Enable secure cookie attributes
- Implement session timeout
- Limit concurrent sessions
- Clean up expired sessions
3. **OAuth Security**
- Validate OAuth state parameter
- Use HTTPS for callbacks
- Validate token scopes
- Handle user data securely
4. **General Security**
- Implement rate limiting
- Use secure password handling
- Log security events
- Regular security audits
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contact
Igor Benav – [@igorbenav](https://x.com/igorbenav) – igormagalhaesr@gmail.com
[github.com/igorbenav](https://github.com/igorbenav/)
Raw data
{
"_id": null,
"home_page": null,
"name": "fastsecure",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "fastapi, authentication, oauth, jwt, session",
"author": null,
"author_email": "Igor Benav <igor.magalhaes.r@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/49/12/c9abbd8e08bbc26898e9db7084cc09619f289f3aefdb3216d6641d59baba/fastsecure-0.3.0.tar.gz",
"platform": null,
"description": "# FastSecure\n\n<p align=\"center\">\n <a href=\"https://igorbenav.github.io/fastsecure/\">\n <img src=\"docs/assets/FastSecure.png\" alt=\"FastSecure logo\" width=\"65%\" height=\"auto\">\n </a>\n</p>\n\nA modern, flexible authentication system for FastAPI applications with support for multiple authentication methods and strategies.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Core Concepts](#core-concepts)\n- [Basic Usage Guide](#basic-usage-guide)\n - [Setting Up JWT Authentication](#setting-up-jwt-authentication)\n - [Setting Up Session Authentication](#setting-up-session-authentication)\n - [Setting Up OAuth Authentication](#setting-up-oauth-authentication)\n- [Advanced Usage Guide](#advanced-usage-guide)\n - [Combining Authentication Methods](#combining-authentication-methods)\n - [Custom Authentication Providers](#custom-authentication-providers)\n - [Storage Backends](#storage-backends)\n- [Security Best Practices](#security-best-practices)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n\n> [!WARNING] \n> FastSecure is still experimental.\n\n## Features\n\n- \ud83d\udd10 **Multiple Authentication Methods**\n - JWT tokens with refresh token support and flexible configuration\n - Session-based authentication with configurable storage backends\n - OAuth 2.0 providers (Google, GitHub) with standardized user info\n - Easy to extend with custom authentication providers\n\n- \ud83d\udd04 **Flexible Authentication Strategies**\n - Use single or multiple authentication methods\n - Support for AND logic (require all methods)\n - Support for OR logic (allow any method)\n - Optional authentication methods\n - Path-based authentication requirements\n\n- \ud83d\uddc4\ufe0f **Session Storage Options**\n - In-memory storage for development\n - Redis backend for distributed systems\n - Database backend (SQLAlchemy) for persistence\n - Easy to implement custom storage backends\n\n- \ud83d\udee1\ufe0f **Security Features**\n - Token expiration and refresh\n - Session timeout and cleanup\n - Concurrent session limits\n - Scope-based authorization\n - IP tracking and user agent logging\n\n## Installation\n\n1. Install using pip:\n```bash\npip install fastsecure\n```\n\n2. Install using uv or poetry:\n```bash\nuv add fastsecure\n```\n\n```bash\npoetry add fastsecure\n```\n\n## Core Concepts\n\nBefore diving into the implementation, let's understand the core concepts:\n\n### Authentication Manager\n\nThe `AuthenticationManager` is the central component that:\n- Manages authentication providers\n- Handles authentication strategies\n- Enforces authentication requirements\n- Coordinates the authentication flow\n\n### Authentication Providers\n\nProviders implement specific authentication methods:\n- JWT tokens\n- Sessions\n- OAuth\n- Custom methods\n\n### Authentication Strategies\n\nStrategies determine how multiple authentication methods are combined:\n- `AuthStrategy.ANY`: Any provider can authenticate (OR logic)\n- `AuthStrategy.ALL`: All providers must authenticate (AND logic)\n\n### Authentication Requirements\n\nRequirements specify which authentication methods are needed for specific paths:\n- Required providers\n- Optional providers\n- Authentication strategy\n- Required scopes\n\n## Basic Usage Guide\n\n### Setting Up JWT Authentication\n\n1. **Create a Basic FastAPI Application**\n\n```python\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom fastsecure import AuthenticationManager, JWTAuthenticationProvider\n\napp = FastAPI()\n```\n\n2. **Initialize Authentication Manager and JWT Provider**\n\n```python\n# Initialize authentication\nauth_manager = AuthenticationManager()\n\n# Configure JWT provider\njwt_auth = JWTAuthenticationProvider(\n secret_key=\"your-secret-key\", # Use a secure key in production!\n access_token_expire_minutes=30,\n refresh_token_expire_days=7\n)\n\n# Register the provider\nauth_manager.register_provider(\"jwt\", jwt_auth)\n```\n\n3. **Create Authentication Dependency**\n\n```python\nfrom fastapi import Request\nfrom typing import Optional\n\nasync def requires_auth(request: Request, path: Optional[str] = None) -> dict:\n \"\"\"\n FastAPI dependency for authentication requirements.\n \n Args:\n request: The FastAPI request object\n path: Optional path override for authentication requirements\n \n Returns:\n Authentication result if successful\n \n Raises:\n HTTPException: If authentication fails\n \"\"\"\n # Get authentication data from request headers\n auth_header = request.headers.get(\"Authorization\")\n if not auth_header:\n raise HTTPException(status_code=401, detail=\"No authentication provided\")\n \n # Parse Bearer token\n try:\n scheme, token = auth_header.split()\n if scheme.lower() != \"bearer\":\n raise HTTPException(status_code=401, detail=\"Invalid authentication scheme\")\n except ValueError:\n raise HTTPException(status_code=401, detail=\"Invalid authorization header\")\n \n # Authenticate using the manager\n result = await auth_manager.authenticate(\n path or request.url.path,\n {\"jwt\": {\"access_token\": token}}\n )\n \n if not result.success:\n raise HTTPException(\n status_code=401,\n detail=\"Authentication failed\",\n headers={\"WWW-Authenticate\": \"Bearer\"}\n )\n \n return result\n\n```\n\n4. **Configure Protected Routes**\n\n```python\n# Add authentication requirement for protected paths\nauth_manager.add_requirement(\n \"/api/protected/*\", # Path pattern\n providers=[\"jwt\"], # Required providers\n scopes=[\"read\"] # Required scopes (optional)\n)\n```\n\n5. **Implement Login and Protected Routes**\n\n```python\nfrom pydantic import BaseModel\n\nclass LoginCredentials(BaseModel):\n username: str\n password: str\n\n@app.post(\"/api/auth/login\")\nasync def login(credentials: LoginCredentials):\n # Validate credentials (implement your own validation)\n user_id = validate_credentials(credentials)\n \n # Authenticate with JWT provider\n result = await auth_manager.authenticate(\n \"/api/protected/data\",\n {\"jwt\": {\n \"user_id\": user_id,\n \"scopes\": [\"read\", \"write\"]\n }}\n )\n \n if not result.success:\n raise HTTPException(401, \"Authentication failed\")\n \n return {\n \"access_token\": result.access_token,\n \"refresh_token\": result.refresh_token,\n \"token_type\": \"Bearer\",\n \"expires_at\": result.expires_at\n }\n\n@app.get(\"/api/protected/data\")\nasync def protected_data(auth = Depends(requires_auth)):\n return {\n \"message\": \"Authenticated!\",\n \"user_id\": auth.user_id,\n \"scopes\": auth.metadata.get(\"scopes\", [])\n }\n```\n\n### Setting Up Session Authentication\n\n1. **Choose a Storage Backend**\n\n```python\nfrom fastsecure import (\n SessionAuthenticationProvider,\n RedisSessionStore,\n DatabaseSessionStore\n)\n\n# For development (in-memory)\nsession_auth = SessionAuthenticationProvider()\n\n# For production with Redis\nsession_auth = SessionAuthenticationProvider(\n session_store=RedisSessionStore(\"redis://localhost\"),\n session_timeout_minutes=60,\n max_sessions_per_user=3,\n cleanup_expired=True\n)\n```\n\n2. **Configure Session Authentication**\n\n```python\n# Register the provider\nauth_manager.register_provider(\"session\", session_auth)\n\n# Add requirements\nauth_manager.add_requirement(\n \"/api/user/*\",\n providers=[\"session\"]\n)\n```\n\n3. **Implement Session Login**\n\n```python\n@app.post(\"/api/auth/session/login\")\nasync def session_login(\n credentials: LoginCredentials,\n request: Request\n):\n user_id = validate_credentials(credentials)\n \n result = await auth_manager.authenticate(\n \"/api/user/profile\",\n {\"session\": {\n \"user_id\": user_id,\n \"ip_address\": request.client.host,\n \"user_agent\": request.headers.get(\"user-agent\"),\n \"scopes\": [\"user:read\"]\n }}\n )\n \n if not result.success:\n raise HTTPException(401, \"Authentication failed\")\n \n response = JSONResponse({\n \"message\": \"Logged in successfully\",\n \"user_id\": user_id\n })\n \n # Set session cookie\n response.set_cookie(\n \"session_id\",\n result.session_id,\n httponly=True,\n secure=True,\n samesite=\"lax\",\n expires=result.expires_at\n )\n \n return response\n```\n\n### Setting Up OAuth Authentication\n\n1. **Configure OAuth Providers**\n\n```python\nfrom fastsecure import GoogleAuthProvider, GitHubAuthProvider\n\n# Google Sign-In\ngoogle_auth = GoogleAuthProvider(\n client_id=\"your-client-id\",\n client_secret=\"your-client-secret\",\n redirect_uri=\"http://localhost:8000/auth/google/callback\"\n)\n\n# GitHub Sign-In\ngithub_auth = GitHubAuthProvider(\n client_id=\"your-client-id\",\n client_secret=\"your-client-secret\",\n redirect_uri=\"http://localhost:8000/auth/github/callback\"\n)\n\n# Register providers\nauth_manager.register_provider(\"google\", google_auth)\nauth_manager.register_provider(\"github\", github_auth)\n```\n\n2. **Implement OAuth Flow**\n\n```python\n@app.get(\"/auth/google/login\")\nasync def google_login():\n authorization_url = google_auth.get_authorization_url(\n state=\"random-secure-state\" # Implement secure state handling\n )\n return RedirectResponse(authorization_url)\n\n@app.get(\"/auth/google/callback\")\nasync def google_callback(code: str, state: str):\n # Validate state\n validate_oauth_state(state)\n \n result = await auth_manager.authenticate(\n \"/api/user/profile\",\n {\"google\": {\"code\": code}}\n )\n \n if not result.success:\n raise HTTPException(401, \"Authentication failed\")\n \n # Get user info from result\n user_info = result.metadata[\"user_info\"]\n \n return {\n \"message\": \"Logged in with Google\",\n \"email\": user_info[\"email\"],\n \"name\": user_info[\"name\"],\n \"access_token\": result.access_token\n }\n```\n\n## Advanced Usage Guide\n\n### Combining Authentication Methods\n\n1. **Require Multiple Methods (AND Strategy)**\n\n```python\n# Require both JWT and session authentication\nauth_manager.add_requirement(\n \"/api/admin/*\",\n providers=[\"jwt\", \"session\"],\n strategy=AuthStrategy.ALL,\n scopes=[\"admin\"]\n)\n\n# Example request handler\n@app.post(\"/api/admin/action\")\nasync def admin_action(auth = Depends(auth_manager.requires_auth)):\n if \"admin\" not in auth.metadata.get(\"scopes\", []):\n raise HTTPException(403, \"Insufficient permissions\")\n return {\"message\": \"Admin action successful\"}\n```\n\n2. **Allow Alternative Methods (OR Strategy)**\n\n```python\n# Allow any authentication method\nauth_manager.add_requirement(\n \"/api/user/*\",\n providers=[\"jwt\", \"session\", \"google\"],\n strategy=AuthStrategy.ANY\n)\n```\n\n3. **Optional Authentication**\n\n```python\n# Add optional authentication methods\nauth_manager.add_requirement(\n \"/api/public/*\",\n providers=[\"jwt\"],\n optional_providers=[\"session\", \"google\"]\n)\n```\n\n### Custom Authentication Providers\n\n1. **Create a Custom Provider**\n\n```python\nfrom fastsecure import AuthenticationProvider, AuthenticationResult\nfrom typing import Dict, Any, Set\n\nclass APIKeyAuthProvider(AuthenticationProvider):\n def __init__(self, api_keys: Dict[str, str]):\n self.api_keys = api_keys\n \n def get_required_credentials(self) -> Set[str]:\n return {\"api_key\"}\n \n async def authenticate(\n self,\n credentials: Dict[str, Any]\n ) -> AuthenticationResult:\n api_key = credentials.get(\"api_key\")\n \n if api_key not in self.api_keys:\n return AuthenticationResult(\n success=False,\n provider=self.provider_name,\n metadata={\"error\": \"Invalid API key\"}\n )\n \n return AuthenticationResult(\n success=True,\n provider=self.provider_name,\n user_id=self.api_keys[api_key],\n metadata={\"api_key\": api_key}\n )\n \n async def validate_authentication(\n self,\n auth_data: Dict[str, Any]\n ) -> bool:\n return auth_data.get(\"api_key\") in self.api_keys\n```\n\n2. **Register and Use Custom Provider**\n\n```python\n# Initialize with API keys\napi_key_auth = APIKeyAuthProvider({\n \"key1\": \"user1\",\n \"key2\": \"user2\"\n})\n\n# Register provider\nauth_manager.register_provider(\"apikey\", api_key_auth)\n\n# Add requirement\nauth_manager.add_requirement(\n \"/api/service/*\",\n providers=[\"apikey\"]\n)\n```\n\n### Storage Backends\n\n1. **Implement Custom Session Storage**\n\n```python\nfrom fastsecure import SessionStore\nfrom typing import Dict, Any, List, Optional\nfrom datetime import datetime\n\nclass CustomSessionStore(SessionStore):\n async def create_session(\n self,\n user_id: int,\n session_id: str,\n expires_at: datetime,\n metadata: Dict[str, Any]\n ) -> bool:\n # Implement session creation\n pass\n \n async def get_session(\n self,\n session_id: str\n ) -> Optional[Dict[str, Any]]:\n # Implement session retrieval\n pass\n \n async def update_session(\n self,\n session_id: str,\n metadata: Dict[str, Any]\n ) -> bool:\n # Implement session update\n pass\n \n async def delete_session(\n self,\n session_id: str\n ) -> bool:\n # Implement session deletion\n pass\n \n async def get_user_sessions(\n self,\n user_id: int\n ) -> List[Dict[str, Any]]:\n # Implement user sessions retrieval\n pass\n```\n\n## Security Best Practices\n\n1. **JWT Security**\n - Use strong secret keys\n - Set appropriate token expiration times\n - Implement token refresh securely\n - Use HTTPS for token transmission\n\n2. **Session Security**\n - Enable secure cookie attributes\n - Implement session timeout\n - Limit concurrent sessions\n - Clean up expired sessions\n\n3. **OAuth Security**\n - Validate OAuth state parameter\n - Use HTTPS for callbacks\n - Validate token scopes\n - Handle user data securely\n\n4. **General Security**\n - Implement rate limiting\n - Use secure password handling\n - Log security events\n - Regular security audits\n\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Contact\n\nIgor Benav \u2013 [@igorbenav](https://x.com/igorbenav) \u2013 igormagalhaesr@gmail.com\n[github.com/igorbenav](https://github.com/igorbenav/)\n",
"bugtrack_url": null,
"license": null,
"summary": "Flexible authentication system for FastAPI applications",
"version": "0.3.0",
"project_urls": null,
"split_keywords": [
"fastapi",
" authentication",
" oauth",
" jwt",
" session"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ca0359dd272c39997f1fbfe11fdac7cb2185608aad2166312a86c3437e219d0b",
"md5": "c091e3d02469ba5bab50952190a22ee1",
"sha256": "33050a45af64771b49967a63de8d892e54c0c4f5e2ca391b0e7f98221dbbfa89"
},
"downloads": -1,
"filename": "fastsecure-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c091e3d02469ba5bab50952190a22ee1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 42045,
"upload_time": "2025-02-11T22:30:30",
"upload_time_iso_8601": "2025-02-11T22:30:30.567357Z",
"url": "https://files.pythonhosted.org/packages/ca/03/59dd272c39997f1fbfe11fdac7cb2185608aad2166312a86c3437e219d0b/fastsecure-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4912c9abbd8e08bbc26898e9db7084cc09619f289f3aefdb3216d6641d59baba",
"md5": "2321aa1506cd23901a41b6e693f2edf9",
"sha256": "bfaf9830965fce198c0ff2c4b0cfea2c5d153b79dd92fa64c3c0555a009b64e9"
},
"downloads": -1,
"filename": "fastsecure-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "2321aa1506cd23901a41b6e693f2edf9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 47028,
"upload_time": "2025-02-11T22:30:32",
"upload_time_iso_8601": "2025-02-11T22:30:32.704144Z",
"url": "https://files.pythonhosted.org/packages/49/12/c9abbd8e08bbc26898e9db7084cc09619f289f3aefdb3216d6641d59baba/fastsecure-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-11 22:30:32",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "fastsecure"
}