Building Secure APIs with FastAPI and Azure AD Authentication
Published on September 2, 2025
In today's world of microservices and API-first architecture, securing your endpoints is crucial. In this blog post, we'll explore how to create a simple yet secure FastAPI application that integrates with Azure Active Directory (Azure AD) for authentication using bearer tokens.
What We're Building
Our FastAPI application demonstrates:
- Bearer token authentication using JWT tokens from Azure AD
- Token validation without signature verification (for demonstration purposes)
- User information extraction from the JWT payload
- Protected endpoints that require valid authentication
The Architecture
The application consists of a single FastAPI server with:
- A token verification function that validates Azure AD JWT tokens
- A protected
/hello
endpoint that returns user information - Integration with Azure AD using tenant-specific configuration
Key Components
1. Azure AD Configuration
TENANT_ID = "6213dbca-6fe9-42b2-bdaa-ccf2fc2f6332"
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
APP_ID_URI = "b1c47286-f990-408a-8d6e-938377129947"
CLIENT_ID = "b1c47286-f990-408a-8d6e-938377129947"
SECRET_KEY = "APP Secret Key"
These configuration values connect your application to a specific Azure AD tenant and define the valid audiences for token validation.
2. Token Verification
The verify_token
function is the heart of our authentication system:
- Extracts bearer tokens from the Authorization header
- Decodes JWT tokens without signature verification (⚠️ Note: In production, always verify signatures!)
- Validates the audience to ensure tokens are intended for this application
- Handles common JWT errors like expired or malformed tokens
3. Protected Endpoints
Our /hello
endpoint demonstrates how to:
- Require authentication using FastAPI's dependency injection
- Extract user information from the token payload
- Return personalized responses based on the authenticated user
What Makes This Special
- Simple Integration: Just a few lines of code to secure your endpoints
- Enterprise Ready: Uses Azure AD, which is widely adopted in corporate environments
- User Context: Extracts meaningful user information like username and employee ID
- Scope Awareness: Can handle OAuth scopes for fine-grained permissions
Running the Application
Getting started is straightforward:
# Install dependencies
pip install fastapi uvicorn python-jose[cryptography]
# Run the server
uvicorn main:app --reload --host 0.0.0.0 --port 8000
from fastapi import FastAPI, Depends, HTTPException, statusfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentialsimport uvicornimport jwt
app = FastAPI(title="FastAPI Authentication Example")security = HTTPBearer()
TENANT_ID = "6213dbca-6fe9-42b2-bdaa-ccf2fc2f6332"AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"APP_ID_URI = "b1c47286-f990-408a-8d6e-938377129947" CLIENT_ID = "b1c47286-f990-408a-8d6e-938377129947"SECRET_KEY = "APP Secret Key"VALID_AUDIENCES = [APP_ID_URI, CLIENT_ID]
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)): """Verify the bearer token using JWT validation""" try: decoded = jwt.decode(credentials.credentials, options={"verify_signature": False}) audience = decoded.get("aud") if audience not in VALID_AUDIENCES: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token audience", headers={"WWW-Authenticate": "Bearer"}, ) return decoded except jwt.ExpiredSignatureError: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Token has expired", headers={"WWW-Authenticate": "Bearer"}, ) except jwt.InvalidTokenError: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token format", headers={"WWW-Authenticate": "Bearer"}, )
@app.get("/hello")async def hello_world(decoded_token: dict = Depends(verify_token)): """Protected hello world endpoint""" username = decoded_token.get("preferred_username", "Unknown User") employee_id = decoded_token.get("employeeid", "Unknown") return { "message": "Hello World! You are authenticated.", "user": username, "employee_id": employee_id, "scopes": decoded_token.get("scp", "").split(" ") }
if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000)
The application will be available at http://localhost:8000
, with automatic API documentation at http://localhost:8000/docs
.
Testing the Authentication
To test the protected endpoint, you'll need a valid Azure AD token:
curl -H "Authorization: Bearer YOUR_AZURE_AD_TOKEN" \
http://localhost:8000/hello
A successful response will look like:
{
"message": "Hello World! You are authenticated.",
"user": "john.doe@company.com",
"employee_id": "EMP123",
"scopes": ["read", "write"]
}
Security Considerations
While this example demonstrates the basics, remember these important points for production use:
- Always verify token signatures - Don't set
verify_signature: False
in production - Use HTTPS - Never transmit tokens over unencrypted connections
- Validate all claims - Check issuer, expiration, and other relevant claims
- Implement rate limiting - Protect against abuse and brute force attacks
- Log security events - Monitor authentication failures and suspicious activity
Conclusion
FastAPI's elegant dependency injection system makes it incredibly easy to add authentication to your APIs. Combined with Azure AD's robust identity platform, you can quickly build secure, enterprise-ready applications.
This example provides a solid foundation that you can extend with additional features like:
- Role-based authorization
- API key authentication
- Multi-tenant support
- Advanced logging and monitoring
The complete code is available in this repository, ready for you to experiment with and adapt to your specific needs.
Ready to secure your APIs? Start with this example and build from there. FastAPI and Azure AD make a powerful combination for modern web applications.
Technologies Used
- FastAPI - Modern, fast web framework for building APIs
- Azure Active Directory - Microsoft's cloud-based identity service
- JWT - JSON Web Tokens for secure information transmission
- Python-JOSE - JWT library for Python
- Uvicorn - Lightning-fast ASGI server
Resources
- FastAPI Documentation
- Azure AD Authentication Documentation
- JWT.io - JWT debugger and documentation