Adds DAB database policies that filter data per user. Users authenticate with Microsoft Entra ID. The web app sends a bearer token to DAB. DAB connects to SQL using SAMI.
The difference in this quickstart is policy enforcement inside DAB. The API reads claims from the token and applies database policies to restrict what data a user can access. Each authenticated user only sees their own todos.
- Apply DAB database policies (
@item.Owner eq @claims.preferred_username) - Enforce per-user data isolation with zero custom API code
- Use MSAL in a SPA with auto-redirect (no manual login)
- Pass bearer tokens from web → API
| Hop | Local | Azure |
|---|---|---|
| User → Web | Entra ID (auto-redirect) | Entra ID (auto-redirect) |
| Web → API | Bearer token | Bearer token |
| API → SQL | SQL Auth + policy | SAMI + policy |
flowchart LR
U[User]
subgraph Microsoft Entra
E[App Registration]
end
subgraph Azure Container Apps
W[Web App]
A[Data API builder<br/><i>With Database Policy</i>]
end
subgraph Azure SQL
S[(Database)]
end
U <-->|Login| E
E -.-> W
U -->|OAuth| W -->|Bearer Token| A
A -->|SAMI| S
Considerations on DAB Policy: Identity now flows through the system. DAB enforces data access rules based on user claims. The database trusts DAB's identity, but DAB is responsible for applying user-level filtering.
- .NET 8 or later
- Aspire workload —
dotnet workload install aspire - Azure CLI (for Entra ID setup)
- Data API Builder CLI —
dotnet tool restore - Docker Desktop
- PowerShell
Azure Permissions Required: Create app registrations in Entra ID.
dotnet tool restore
az login
dotnet run --project aspire-apphostOn first run, Aspire detects that Entra ID isn't configured and offers to run azure/entra-setup.ps1 interactively. This creates the app registration, updates config.js and dab-config.json, then starts normally.
The web app auto-redirects to Microsoft login. Once signed in, all API calls include bearer tokens, and each user only sees rows they own.
pwsh ./azure-infra/azure-up.ps1The preprovision hook runs entra-setup.ps1 automatically. During teardown via azure-down.ps1, the postdown hook runs entra-teardown.ps1 to delete the app registration.
To tear down resources:
pwsh ./azure-infra/azure-down.ps1DAB applies this policy on every read, update, and delete:
@item.Owner eq @claims.preferred_username
This means the signed-in user can only access rows where Owner matches their Entra ID UPN. No custom API code required.
To restrict access to rows where the Owner matches the user's subject claim:
{
"entities": {
"Todos": {
"permissions": [
{
"role": "authenticated",
"actions": [
{
"action": "read",
"policy": {
"database": "@item.Owner eq @claims.preferred_username"
}
}
]
}
]
}
}
}| File | Purpose |
|---|---|
api/dab-config.json |
Uses authenticated role and adds policy to read, update, and delete actions |
web/auth.js |
MSAL with auto-redirect (no manual login button) |
web/index.html |
Adds MSAL CDN, delays add-form display until auth, adds auth.js script |
web/app.js |
Uses initializeApp() async init with auth and updateUI() for signed-in state |
web/dab.js |
Sends bearer token with every API call via getAuthHeaders() |
web/config.js |
Defines clientId and tenantId for MSAL configuration |
This quickstart includes the full auth flow: MSAL, auto-redirect, bearer tokens,
authenticatedrole, and per-user policies.