Azure App Registrations for a Frontend and Backend (SPAs + APIs) - Part 2
In Part 1, we configured Azure App Registrations for a frontend and a backend using OAuth 2.0 with Azure AD. Now, let’s bring the backend to life using FastAPI and protect it with Azure AD authentication using the excellent fastapi-azure-auth
library.
By the end of this tutorial, you’ll have:
- A working FastAPI backend serving student data
- Azure AD-based authentication using OAuth2
- Swagger UI support for testing tokens locally
🧰 Prerequisites
Make sure you’ve completed Part 1 of this series and have:
- Two app registrations (
devopswithdave-fe
anddevopswithdave-be
) - An exposed scope (
access_as_user
) in the backend app - Frontend client ID and backend API URI ready
🏗 Step 1: Set Up Your FastAPI Project
🔹 Create and Activate a Virtual Environment
python -m venv venv
source venv/bin/activate # For macOS/Linux
venv\Scripts\activate # For Windows
source ./venv/Scripts/activate # For Windows using git bash
🔹 Install Required Packages
pip install fastapi uvicorn fastapi-azure-auth python-dotenv
📁 Step 2: Create the API Structure
We’ll organize our app with a simple folder layout:
.
├── .env
├── auth.py
├── main.py
└── students/
├── students.py
└── students.json
.env
Create a .env
file to store your secrets securely (this file should not be committed to version control):
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_API_SCOPE=api://devopswithdave-be/access_as_user
FRONTEND_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Add .env
to your .gitignore
.
students/students.json
Use Mockaroo to generate dummy data, or use the provided JSON sample. Save it as:
students/students.json
📦 You can find a full dataset example in the GitHub repo.
students/students.py
import json
from fastapi import APIRouter
router = APIRouter(
prefix="/api/students",
responses={404: {"description": "Endpoint not found"}}
)
@router.get("/")
async def get_students():
with open('./students/students.json', 'r', encoding='utf-8') as file_object:
return json.load(file_object)
auth.py
import os
from dotenv import load_dotenv
from fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer
load_dotenv()
azure_scheme = SingleTenantAzureAuthorizationCodeBearer(
app_client_id=os.getenv("AZURE_CLIENT_ID"),
tenant_id=os.getenv("AZURE_TENANT_ID"),
scopes={os.getenv("AZURE_API_SCOPE"): "access_as_user"},
allow_guest_users=True
)
main.py
import os
from dotenv import load_dotenv
from fastapi import FastAPI, Security
from fastapi.middleware.cors import CORSMiddleware
from students import students
from auth import azure_scheme
load_dotenv()
app = FastAPI(
swagger_ui_oauth2_redirect_url='/oauth2-redirect',
swagger_ui_init_oauth={
'usePkceWithAuthorizationCodeGrant': True,
'clientId': os.getenv("FRONTEND_CLIENT_ID"),
'scopes': os.getenv("AZURE_API_SCOPE")
},
)
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
app.include_router(students.router, dependencies=[Security(azure_scheme)])
🔐 Step 3: Configure Azure Redirect URIs
To test Swagger’s OAuth login locally:
- Go to Azure Portal
- Navigate to Frontend app registration (
devopswithdave-fe
) - Under Authentication > Single-page application, add:
http://localhost:8000/oauth2-redirect
💡 This URI is used by Swagger UI to handle the OAuth 2.0 code grant flow.
▶ Step 4: Run Your FastAPI App
uvicorn main:app --reload
Visit http://localhost:8000/docs
You should see:
- A secured
/api/students/
endpoint - A “Authorize” button in Swagger UI
- A working OAuth login flow using Azure AD
🗂 Full Code
🔗 GitHub Repo: furmidgeuk/fastapi-azure-auth
🧪 Next Steps
You now have:
- A secure FastAPI backend using Azure AD
- Environment-based secrets management
- A pattern you can reuse across projects