fastsecure


Namefastsecure JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryFlexible authentication system for FastAPI applications
upload_time2025-02-11 22:30:32
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
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"
}
        
Elapsed time: 0.48224s