{"id":6625,"library":"fastapi-azure-auth","title":"FastAPI Azure Auth","description":"FastAPI-Azure-Auth is a Python library that provides an easy and secure implementation of Azure Entra ID (formerly Azure Active Directory) authentication and authorization for FastAPI APIs. It supports B2C, single-tenant, and multi-tenant applications. The library is actively maintained, with frequent updates, and is currently at version 5.2.0.","status":"active","version":"5.2.0","language":"en","source_language":"en","source_url":"https://github.com/intility/fastapi-azure-auth","tags":["ad","async","asyncio","authentication","authorization","azure","azure ad","azure entra id","azure entra","entra id","azuread","fastapi","multi tenant","oauth2","oidc","security","single tenant","starlette"],"install":[{"cmd":"pip install fastapi-azure-auth uvicorn","lang":"bash","label":"Install with uvicorn"}],"dependencies":[{"reason":"The core web framework this library integrates with.","package":"fastapi"},{"reason":"Used for cryptographic operations, specified as a direct dependency.","package":"cryptography"},{"reason":"An HTTP client for making requests, specified as a direct dependency.","package":"httpx"},{"reason":"Replaced 'python-jose' for JWT handling in version 4.4.0.","package":"pyjwt"},{"reason":"Recommended for managing application settings, especially for loading from .env files.","package":"pydantic-settings"},{"reason":"An ASGI server to run the FastAPI application.","package":"uvicorn"}],"imports":[{"symbol":"FastAPI","correct":"from fastapi import FastAPI"},{"symbol":"Security","correct":"from fastapi import Security"},{"symbol":"Depends","correct":"from fastapi import Depends"},{"symbol":"SingleTenantAzureAuthorizationCodeBearer","correct":"from fastapi_azure_auth.auth import SingleTenantAzureAuthorizationCodeBearer"},{"symbol":"MultiTenantAzureAuthorizationCodeBearer","correct":"from fastapi_azure_auth.auth import MultiTenantAzureAuthorizationCodeBearer"},{"symbol":"B2CMultiTenantAuthorizationCodeBearer","correct":"from fastapi_azure_auth.auth import B2CMultiTenantAuthorizationCodeBearer"},{"symbol":"User","correct":"from fastapi_azure_auth.user import User"},{"symbol":"BaseSettings","correct":"from pydantic_settings import BaseSettings"},{"symbol":"SettingsConfigDict","correct":"from pydantic_settings import SettingsConfigDict"}],"quickstart":{"code":"import os\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom pydantic import AnyHttpUrl\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\nfrom fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer\nfrom fastapi_azure_auth.user import User\n\n\nclass Settings(BaseSettings):\n    BACKEND_CORS_ORIGINS: list[str | AnyHttpUrl] = ['http://localhost:8000']\n    TENANT_ID: str = os.environ.get('TENANT_ID', '')\n    APP_CLIENT_ID: str = os.environ.get('APP_CLIENT_ID', '')\n    OPENAPI_CLIENT_ID: str = os.environ.get('OPENAPI_CLIENT_ID', '')\n    SCOPE_DESCRIPTION: str = os.environ.get('SCOPE_DESCRIPTION', 'user_impersonation')\n    \n    model_config = SettingsConfigDict(\n        env_file='.env', env_file_encoding='utf-8', case_sensitive=True\n    )\n\n    @property\n    def SCOPE_NAME(self) -> str:\n        return f'api://{self.APP_CLIENT_ID}/{self.SCOPE_DESCRIPTION}'\n    \n    @property\n    def SCOPES(self) -> dict:\n        return {self.SCOPE_NAME: self.SCOPE_DESCRIPTION}\n\nsettings = Settings()\n\n# Configure Azure AD authentication scheme\nazure_scheme = SingleTenantAzureAuthorizationCodeBearer(\n    app_client_id=settings.APP_CLIENT_ID,\n    tenant_id=settings.TENANT_ID,\n    scopes=settings.SCOPES,\n)\n\napp = FastAPI(\n    swagger_ui_oauth2_redirect_url='/oauth2-redirect',\n    swagger_ui_init_oauth={\n        'usePkceWithAuthorizationCodeGrant': True,\n        'clientId': settings.OPENAPI_CLIENT_ID,\n        'scopes': settings.SCOPE_NAME,\n    },\n)\n\n@app.get(\"/authenticated-hello\")\nasync def authenticated_hello(user: User = Depends(azure_scheme)):\n    if not user:\n        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=\"Not authenticated\")\n    return {\"message\": f\"Hello, {user.name}! Your roles: {user.roles}\"}\n\n# To run: uvicorn main:app --reload\n# Make sure to set TENANT_ID, APP_CLIENT_ID, OPENAPI_CLIENT_ID in your .env file or environment variables.\n# Also configure your Azure App Registration with the correct Redirect URIs (e.g., http://localhost:8000/oauth2-redirect).","lang":"python","description":"This quickstart demonstrates setting up a FastAPI application with single-tenant Azure Entra ID authentication. It uses Pydantic-settings to manage configuration from environment variables (or a .env file) and protects an endpoint using the `SingleTenantAzureAuthorizationCodeBearer` scheme. Remember to configure your Azure App Registration with the appropriate Redirect URIs, such as `http://localhost:8000/oauth2-redirect`."},"warnings":[{"fix":"Ensure your Azure App Registration is configured to issue v2 tokens. You can typically change this in the application manifest within the Azure portal.","message":"Azure Entra ID (formerly Active Directory) v1 token support has been dropped. All new and existing projects should migrate to v2 tokens.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Upgrade Pydantic to version 2.x. Review your Pydantic models for any breaking changes introduced in Pydantic v2 (e.g., `Config` class to `model_config`, field definitions).","message":"Pydantic v1 support has been dropped. Your project must use Pydantic v2 or later.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Replace `raise InvalidAuth(detail=\"...\")` with `raise InvalidAuthHttp(detail=\"...\", request=request)` or `raise InvalidAuthWebSocket(detail=\"...\", websocket=websocket)` as appropriate.","message":"The `InvalidAuth` exception class now requires both `detail` and `request` objects. For HTTP or WebSocket contexts, it's recommended to explicitly use `InvalidAuthHttp` or `InvalidAuthWebSocket` respectively.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Ensure the redirect URI in your Azure App Registration (e.g., `http://localhost:8000/oauth2-redirect`) is an exact match for what your FastAPI application exposes. Consistently use either `localhost` or `127.0.0.1`.","message":"A common 'redirect URI mismatch' error can occur if the redirect URI configured in Azure Entra ID does not exactly match the one used by your application. This includes differences between 'localhost' and '127.0.0.1'.","severity":"gotcha","affected_versions":"All versions"},{"fix":"It is generally recommended to disable Azure Easy Auth on the backend API service and rely solely on `fastapi-azure-auth` for token validation, ensuring CORS and token scopes are correctly configured.","message":"Integrating Azure Easy Auth (App Service Authentication/Authorization) directly with `fastapi-azure-auth` in a 2-tier application can lead to conflicts, as Easy Auth's flow might interfere with the library's custom token validation logic.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that the Azure App Registration for the client application has the necessary *application permissions* (app roles), not just delegated permissions, and that these have been granted by an admin. The scope should typically be `api://{APP_CLIENT_ID}/.default`.","message":"When using the client_credentials flow, 'Invalid audience' errors can occur if application permissions (app roles) are not correctly configured and granted by an administrator or the API's owner. Delegated permissions are not sufficient for application-only authentication.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}