Azure App Registrations for a Frontend and Backend (SPAs + APIs) - Part 2

2 minute read

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 and devopswithdave-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:

  1. Go to Azure Portal
  2. Navigate to Frontend app registration (devopswithdave-fe)
  3. 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