A FastAPI application with Microsoft Azure AD token validation using the authlib library.
-
Configure Environment Variables
Update the
.envfile with your Azure AD application details:AZURE_CLIENT_ID=your_client_id_here AZURE_TENANT_ID=your_tenant_id_hereNote:
- Client secret is not required since we're only validating JWT tokens, not performing OAuth flows
-
Install Dependencies
uv sync
-
Run the Application
uv run python main.py
Build the Docker image using the included Dockerfile:
docker build -t python-auth-backend .Run the container with environment variables:
docker run -d \
-p 5000:5000 \
-e AZURE_CLIENT_ID=your_client_id_here \
-e AZURE_TENANT_ID=your_tenant_id_here \
--name auth-backend \
python-auth-backendOr use an .env file:
docker run -d \
-p 5000:5000 \
--env-file .env \
--name auth-backend \
python-auth-backendThe Dockerfile uses a multi-stage build:
- Builder stage: Uses Python 3.14-slim with uv for fast dependency installation
- Runtime stage: Minimal Python 3.14-slim image with only the compiled application
- Port: Exposes port 5000
- Working directory:
/app - Entrypoint: Runs the FastAPI application using the virtual environment's Python
# Build the image
docker build -t python-auth-backend .
# Run the container
docker run -d -p 5000:5000 --env-file .env --name auth-backend python-auth-backend
# View container logs
docker logs auth-backend
# Follow container logs
docker logs -f auth-backend
# Stop the container
docker stop auth-backend
# Remove the container
docker rm auth-backend
# Remove the image
docker rmi python-auth-backend
# Access container shell
docker exec -it auth-backend /bin/bashGET /api/health- Health check endpointGET /api/auth/info- Get authentication configuration info
GET /api/helloworld- Hello World endpoint that requires valid Microsoft token
GET /docs- Interactive Swagger UI documentationGET /redoc- ReDoc documentationGET /openapi.json- OpenAPI schema
-
Without Token (Should return 403)
curl http://localhost:5000/api/helloworld
-
With Valid Microsoft Token
curl -H "Authorization: Bearer YOUR_MICROSOFT_TOKEN" http://localhost:5000/api/helloworld
Note: If running with uv, use uv run python main.py to start the server.
FastAPI automatically generates interactive documentation:
-
Swagger UI: Visit
http://localhost:5000/docs- Interactive API explorer
- Test endpoints directly in the browser
- Try out authentication with Bearer tokens
-
ReDoc: Visit
http://localhost:5000/redoc- Clean, three-panel documentation
- Better for reading API specifications
To get a Microsoft token for testing, you can:
-
Use Azure CLI:
az login az account get-access-token --resource YOUR_CLIENT_ID
-
Or use the Microsoft Graph Explorer or Azure Portal to generate a token.
- β Fast Performance - Built on FastAPI/Starlette for high performance
- β Automatic Documentation - Interactive Swagger UI and ReDoc
- β Type Safety - Pydantic models for request/response validation
- β Microsoft Azure AD token validation
- β JWT token verification with Microsoft's public keys
- β Protected endpoints return 403/401 without valid token
- β User information extraction from valid tokens
- β Environment-based configuration
- β Clean dependency injection for token validation
- β Comprehensive error handling
- Better Performance - 2-3x faster than Flask
- Automatic API Documentation - No need to write docs manually
- Type Hints - Built-in validation and better IDE support
- Modern Python - Async/await support
- Industry Standard - OpenAPI/JSON Schema compliance
The application validates Microsoft tokens by:
- Checking the Authorization header format (Bearer token)
- Fetching Microsoft's public keys (JWKS)
- Verifying the JWT signature
- Validating the issuer and audience claims
- Extracting user information from validated tokens
This project uses uv for fast Python package management:
Installing Dependencies:
uv sync # Install all dependencies from uv.lockAdding New Packages:
uv add package_name # Add a regular dependency
uv add --dev package_name # Add a development dependency
uv add "package_name>=1.0.0" # Add with version constraintUpgrading Dependencies:
uv sync --upgrade # Upgrade all dependencies
uv add package_name --upgrade # Upgrade specific packageRunning Commands:
uv run python main.py # Run Python with project environment
uv run pytest # Run tests with project environmentOther Useful Commands:
uv pip list # List installed packages
uv pip show package_name # Show package information
uv lock # Update the lock fileRun tests:
uv run python test_api.pyThe test script will verify all endpoints and documentation routes.
This project is licensed under the MIT License - see the LICENSE file for details.