Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Deze handleiding laat zien hoe u een gedistribueerde .NET Aspire gedistribueerde toepassing beveiligt met Microsoft Entra ID verificatie en autorisatie. Hierin wordt het volgende behandeld:
-
Blazor Server-front-end (
MyService.Web): Gebruikersaanmelding met OpenID Connect en tokenverwerving -
Protected API backend (
MyService.ApiService): JWT-validatie met behulp van Microsoft. Identity.Web - End-to-end flow: Blazor verkrijgt toegangstokens en roept de beveiligde API aan met Aspire-serviceontdekking
In deze handleiding wordt ervan uitgegaan dat u bent begonnen met een Aspire-project dat is gemaakt met behulp van de volgende opdracht:
aspire new aspire-starter --name MyService
Vereiste voorwaarden
- .NET 9 SDK of hoger
- .NET Aspire CLI - Zie Install Aspire CLI
- Microsoft Entra tenant — Zie Apps registreren in Microsoft Entra ID voor installatie
Aanbeveling
Nieuw bij Aspire? Zie .NET Aspire overzicht.
Inzicht in de werkstroom in twee fasen
Deze handleiding volgt een tweefase-benadering:
| Fase | Wat gebeurt er? | Resultaat |
|---|---|---|
| Fase 1 | Verificatiecode toevoegen met placeholderwaarden | De app bouwt maar werkt niet. |
| Fase 2 | De app-registraties van Microsoft Entra inrichten | App wordt uitgevoerd met echte authenticatie |
Apps registreren in Microsoft Entra ID
Voordat uw app gebruikers kan verifiëren, hebt u twee app-registraties nodig in Microsoft Entra:
| App-registratie | Purpose | Sleutelconfiguratie |
|---|---|---|
API (MyService.ApiService) |
Hiermee worden binnenkomende tokens gevalideerd | App-id-URI, access_as_user bereik |
Web-app (MyService.Web) |
Gebruikers aanmelden, tokens verkrijgen | Omleidings-URI's, clientgeheim, API-machtigingen |
Als u app-registraties al hebt geconfigureerd, hebt u deze waarden nodig voor het appsettings.jsonvolgende:
- TenantId — de tenant-id van uw Microsoft Entra
- API ClientId — Toepassings-id (client) van uw API-app-registratie
-
API-app-id-URI : meestal
api://<api-client-id>(gebruikt inAudiencesenScopes) - Web App ClientId — Toepassings-id (client) van uw web-app-registratie
- Clientgeheim (of certificaat): referentie van de webapp (opslaan in user-secrets, niet in appsettings.json)
-
Machtigingen: de machtigingen die uw web-app aanvraagt, bijvoorbeeld
api://<api-client-id>/.defaultofapi://<api-client-id>/access_as_user
Stap 1: de API registreren
- Ga naar Microsoft Entra-beheercentrum>Identity>Applications>App-registraties.
- Selecteer Nieuwe registratie.
-
Naam:
MyService.ApiService - Ondersteunde accounttypen: Alleen accounts in deze organisatiemap (Single-tenant)
- Selecteer Registreren.
-
Naam:
- Ga naar Blootstellen van een API>Toevoegen naast de toepassings-ID URI.
- Accepteer de standaardwaarde (
api://<client-id>) of pas deze aan. - Selecteer Een bereik toevoegen:
-
Bereiknaam:
access_as_user - Wie kan toestemming geven: Beheerders en gebruikers
- Weergavenaam van beheerderstoestemming: Toegang tot MyService-API
- Beschrijving van beheerderstoestemming: Hiermee kan de app namens de aangemelde gebruiker toegang krijgen tot de MyService-API.
- Selecteer Voeg bereik toe.
-
Bereiknaam:
- Accepteer de standaardwaarde (
- Kopieer de toepassings-id (client): u hebt deze nodig voor beide
appsettings.jsonbestanden.
Zie quickstart: Een app configureren om een web-API beschikbaar te maken voor meer informatie.
Stap 2: de web-app registreren
- Ga naar App-registraties>Nieuwe registratie.
-
Naam:
MyService.Web - Ondersteunde accounttypen: Alleen accounts in deze organisatiemap
-
Omleidings-URI: Selecteer Web en voer de URL van uw app in +
/signin-oidc- Voor lokale ontwikkeling:
https://localhost:7001/signin-oidc(controleer uwlaunchSettings.jsonop de werkelijke poort)
- Voor lokale ontwikkeling:
- Selecteer Registreren.
-
Naam:
- Ga naar Verificatie>toevoegen URI om al uw ontwikkelings-URL's (van
launchSettings.json) toe te voegen. - Ga naar Certificaten en geheimen>Clientgeheimen>Nieuw clientgeheim.
- Voeg een beschrijving en vervaldatum toe.
- Kopieer de geheime waarde onmiddellijk. Deze wordt niet meer weergegeven.
- Ga naar API-machtigingen>Voeg een machtiging>mijn API's toe.
- Selecteer
MyService.ApiService. - Selecteer
access_as_user>machtigingen toevoegen. - Selecteer Beheerderstoestemming verlenen voor [tenant] (of gebruikers worden bij eerste gebruik gevraagd).
- Selecteer
- Kopieer de toepassings-id (client) voor de web-app
appsettings.json.
Opmerking
Sommige organisaties staan geen clientgeheimen toe. Zie Certificaatreferenties of certificaatloze verificatie voor alternatieven.
Zie Quickstart: Een toepassing registreren voor meer informatie.
Stap 3: Configuratie bijwerken
Nadat u de app-registraties hebt gemaakt, werkt u uw appsettings.json bestanden bij:
API (MyService.ApiService/appsettings.json):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "YOUR_TENANT_ID",
"ClientId": "YOUR_API_CLIENT_ID",
"Audiences": ["api://YOUR_API_CLIENT_ID"]
}
}
Web-app (MyService.Web/appsettings.json):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "YOUR_TENANT_ID",
"ClientId": "YOUR_WEB_CLIENT_ID",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [
{ "SourceType": "ClientSecret" }
]
},
"WeatherApi": {
"Scopes": ["api://YOUR_API_CLIENT_ID/.default"]
}
}
Sla het geheim veilig op:
cd MyService.Web
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "YOUR_SECRET_VALUE"
| Waarde | Waar vind ik? |
|---|---|
TenantId |
Microsoft Entra-beheercentrum > Overzicht > Tenant ID |
API ClientId |
App-registraties > MyService.ApiService > Applicatie (client) ID |
Web ClientId |
App-registraties > MyService.Web > Toepassings-ID (client) |
Client Secret |
Gemaakt in stap 2 (direct kopiëren wanneer deze is gemaakt) |
Opmerking
Met de starterssjabloon Aspire wordt automatisch een WeatherApiClient klasse in het MyService.Web project gemaakt. Deze getypte HttpClient wordt in deze handleiding gebruikt om de beveiligde API aan te roepen. U hoeft deze klasse niet zelf te maken. Deze maakt deel uit van de sjabloon.
Snel aan de slag
Deze sectie bevat een beknopte verwijzing voor het toevoegen van verificatie. Zie deel 1 en deel 2 voor gedetailleerde overzichten.
API (MyService.ApiService)
Installeer de Microsoft. Identity.Web NuGet-pakket:
dotnet add package Microsoft.Identity.Web
Voeg de Microsoft Entra-configuratie toe aan appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id>",
"ClientId": "<api-client-id>",
"Audiences": ["api://<api-client-id>"]
}
}
Verificatie en autorisatie registreren in Program.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization();
// ...
app.UseAuthentication();
app.UseAuthorization();
// ...
app.MapGet("/weatherforecast", () => { /* ... */ }).RequireAuthorization();
Web-app (MyService.Web)
Installeer de Microsoft. Identity.Web NuGet-pakket:
dotnet add package Microsoft.Identity.Web
Voeg de Microsoft Entra-configuratie toe aan appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id>",
"ClientId": "<web-client-id>",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [{ "SourceType": "ClientSecret" }]
},
"WeatherApi": { "Scopes": ["api://<api-client-id>/.default"] }
}
Configureer verificatie, token acquisitie en de downstream-API-client in Program.cs.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<BlazorAuthenticationChallengeHandler>();
builder.Services.AddHttpClient<WeatherApiClient>(client =>
client.BaseAddress = new("https+http://apiservice"))
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
// ...
app.UseAuthentication();
app.UseAuthorization();
app.MapGroup("/authentication").MapLoginAndLogout();
De MicrosoftIdentityMessageHandler tokens worden automatisch verkregen en gekoppeld en BlazorAuthenticationChallengeHandler verwerkt toestemmings- en voorwaardelijke toegangsproblemen.
Belangrijk
Vergeet niet om UserInfo.razor aan te maken voor de aanmeldingsknop. Zie Blazor UI-onderdelen toevoegen voor meer informatie.
Opmerking
BlazorAuthenticationChallengeHandler en LoginLogoutEndpointRouteBuilderExtensions worden geleverd in Microsoft.Identity.Web (v3.3.0+). Er is geen bestandskopie vereist.
Bestanden identificeren die moeten worden gewijzigd
De volgende tabel bevat de bestanden die u in elk project wijzigt:
| Project | Bestand | Changes |
|---|---|---|
| ApiService | Program.cs |
JWT Bearer-verificatie, autorisatie-middleware |
appsettings.json |
configuratie van Microsoft Entra | |
.csproj |
Microsoft.Identity.Web toevoegen |
|
| Web | Program.cs |
OIDC-verificatie, verkrijging van token, BlazorAuthenticationChallengeHandler |
appsettings.json |
Microsoft Entra configuratie, downstream-API-bereiken | |
.csproj |
Voeg Microsoft.Identity.Web toe (v3.3.0+) |
|
Components/UserInfo.razor |
Gebruikersinterface voor aanmeldingsknop (nieuw bestand) | |
Components/Layout/MainLayout.razor |
Het onderdeel UserInfo opnemen | |
Components/Routes.razor |
AutoriserenRouteView voor beveiligde pagina's | |
| Pagina's die API's aanroepen | Uitproberen/vangen met ChallengeHandler |
Inzicht in de verificatiestroom
In het volgende diagram ziet u hoe de Blazor-front-end, Microsoft Entra en de beveiligde API communiceren:
flowchart LR
A[User Browser] -->|1 Login OIDC| B[Blazor Server<br/>MyService.Web]
B -->|2 Redirect| C[Microsoft Entra ID]
C -->|3 auth code| B
B -->|4 exchange auth code| C
C -->|5 tokens| B
B -->|6 cookie + session| A
B -->|7 HTTP + Bearer token| D[ASP.NET API<br/>MyService.ApiService<br/>Microsoft.Identity.Web]
D -->|8 Validate JWT| C
D -->|9 Weather data| B
- Gebruiker bezoekt Blazor-app → Niet geauthenticeerd → ziet de knop "Aanmelden".
-
Gebruiker selecteert Login → Wordt doorgestuurd naar
/authentication/login→ OIDC-uitdaging → Microsoft Entra. -
Gebruiker meldt zich aan → Microsoft Entra voert een redirect uit naar
/signin-oidc→ cookie ingesteld. -
Gebruiker navigeert naar de weerpagina → Blazor roept aan
WeatherApiClient.GetAsync(). -
MicrosoftIdentityMessageHandleronderschept de aanvraag, verwerft een token uit de cache (of vernieuwt op de achtergrond) en voegt deAuthorization: Bearer <token>header toe. - API ontvangt aanvraag → Microsoft. Identity.Web valideert de JWT-→ retourneert gegevens.
- Blazor geeft weergegevens weer.
De oplossingsstructuur controleren
Met de starterssjabloon Aspire wordt de volgende projectindeling gemaakt:
MyService/
├── MyService.AppHost/ # Aspire orchestration
├── MyService.ApiService/ # Protected API (Microsoft.Identity.Web)
├── MyService.Web/ # Blazor Server (Microsoft.Identity.Web)
├── MyService.ServiceDefaults/ # Shared defaults
└── MyService.Tests/ # Tests
Deel 1: De API-back-end beveiligen met Microsoft. Identity.Web
In deze sectie wordt het API-project geconfigureerd om JWT Bearer-tokens te valideren die zijn uitgegeven door Microsoft Entra.
Voeg Microsoft toe. Identity.Web-pakket
Voer de volgende opdracht uit om het Microsoft.Identity.Web NuGet-pakket te installeren:
cd MyService.ApiService
dotnet add package Microsoft.Identity.Web
Instellingen voor Microsoft Entra configureren
Voeg de Microsoft Entra-configuratie toe aan MyService.ApiService/appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<your-tenant-id>",
"ClientId": "<your-api-client-id>",
"Audiences": [
"api://<your-api-client-id>"
]
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Belangrijkste eigenschappen:
-
ClientId: registratie-id van api-app Microsoft Entra -
TenantId: uw Microsoft Entra-tenant-id of"organizations"voor multi-tenant of"common"voor elke Microsoft-account -
Audiences: Geldige token-doelgroepen (meestal uw App-ID-URI)
API-Program.cs bijwerken
Vervang de inhoud van MyService.ApiService/Program.cs door de volgende code om JWT Bearer-verificatie toe te voegen en eindpunten te beveiligen:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Add Microsoft.Identity.Web JWT Bearer authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddProblemDetails();
builder.Services.AddOpenApi();
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseExceptionHandler();
app.UseAuthentication();
app.UseAuthorization();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild",
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"];
app.MapGet("/", () =>
"API service is running. Navigate to /weatherforecast to see sample data.");
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.RequireAuthorization();
app.MapDefaultEndpoints();
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Belangrijke wijzigingen:
- JWT Bearer-verificatie registreren bij
AddMicrosoftIdentityWebApi - Voeg
app.UseAuthentication()enapp.UseAuthorization()middleware toe - Toepassen
.RequireAuthorization()op beveiligde eindpunten
De beveiligde API testen
Controleer of de API niet-geverifieerde aanvragen weigert en geldige tokens accepteert.
Een aanvraag zonder token verzenden:
curl https://localhost:<PORT>/weatherforecast
# Expected: 401 Unauthorized
Een aanvraag met een geldig token verzenden:
curl -H "Authorization: Bearer <TOKEN>" https://localhost:<PORT>/weatherforecast
# Expected: 200 OK with weather data
Deel 2: Blazor-front-end configureren voor verificatie
De Blazor Server-app maakt gebruik van Microsoft. Identity.Web voor:
- Gebruikers aanmelden met OIDC
- Toegangstokens verkrijgen om de API aan te roepen
- Tokens koppelen aan uitgaande HTTP-aanvragen
Voeg Microsoft toe. Identity.Web-pakket
Voer de volgende commando uit om het Microsoft.Identity.Web NuGet-pakket te installeren:
cd MyService.Web
dotnet add package Microsoft.Identity.Web
Instellingen voor Microsoft Entra configureren
Voeg de Microsoft Entra-configuratie en downstream-API-bereiken toe aan MyService.Web/appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<your-tenant>.onmicrosoft.com",
"TenantId": "<tenant-guid>",
"ClientId": "<web-app-client-id>",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret": "<your-client-secret>"
}
]
},
"WeatherApi": {
"Scopes": [ "api://<api-client-id>/.default" ]
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Configuratiedetails:
-
ClientId: Registratie-id van web-app (niet de API-id) -
ClientCredentials: Referenties voor de webapp om tokens te verkrijgen. Ondersteunt meerdere referentietypen. Zie het overzicht van referenties voor opties die gereed zijn voor productie. -
Scopes: moet overeenkomen met de app-id-URI van de API met/.defaultachtervoegsel
Waarschuwing
Gebruik voor productie certificaten of beheerde identiteit in plaats van clientgeheimen. Zie Certificaatloze verificatie voor de aanbevolen benadering.
Web-app-Program.cs bijwerken
Vervang de inhoud van MyService.Web/Program.cs met de volgende code om OIDC-authenticatie, tokenverwerking en de downstream API-client te configureren.
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
using MyService.Web;
using MyService.Web.Components;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Authentication + Microsoft Identity Web
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddCascadingAuthenticationState();
// Blazor components
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
// Blazor authentication challenge handler for incremental consent and Conditional Access
builder.Services.AddScoped<BlazorAuthenticationChallengeHandler>();
builder.Services.AddOutputCache();
// Downstream API client with MicrosoftIdentityMessageHandler
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
// Aspire service discovery: resolves "apiservice" at runtime
client.BaseAddress = new("https+http://apiservice");
})
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
app.UseOutputCache();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
// Login/Logout endpoints with incremental consent support
app.MapGroup("/authentication").MapLoginAndLogout();
app.MapDefaultEndpoints();
app.Run();
Belangrijkste punten:
-
AddMicrosoftIdentityWebApp: Hiermee configureert u OIDC-verificatie -
EnableTokenAcquisitionToCallDownstreamApi: Hiermee schakelt u tokenverwerving in voor downstream-API's -
AddScoped<BlazorAuthenticationChallengeHandler>: verwerkt incrementele toestemming en voorwaardelijke toegang in Blazor Server -
AddMicrosoftIdentityMessageHandler: Bearer-tokens automatisch koppelen aan HttpClient-aanvragen -
https+http://apiservice: Aspire service-ontdekking zet dit om naar de werkelijke API-URL -
Middlewarevolgorde:
UseAuthentication()→UseAuthorization()→ eindpunten
De AddMicrosoftIdentityMessageHandler extensie ondersteunt meerdere configuratiepatronen:
Optie 1: Configuratie van appsettings.json (eerder weergegeven)
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
Optie 2: Inline-configuratie met Action-delegate
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
});
Optie 3: Configuratie per aanvraag (parameterloos)
.AddMicrosoftIdentityMessageHandler();
// Then in your service, configure per-request:
var request = new HttpRequestMessage(HttpMethod.Get, "/weatherforecast")
.WithAuthenticationOptions(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
});
var response = await _httpClient.SendAsync(request);
Blazor UI-onderdelen toevoegen
Belangrijk
Deze stap wordt vaak vergeten. Zonder het onderdeel UserInfo kunnen gebruikers zich niet aanmelden.
BlazorAuthenticationChallengeHandler en LoginLogoutEndpointRouteBuilderExtensions worden geleverd in Microsoft.Identity.Web v3.3.0+. Ze zijn automatisch beschikbaar zodra u naar het pakket verwijst. Er is geen bestandskopie vereist.
Maken MyService.Web/Components/UserInfo.razor:
@using Microsoft.AspNetCore.Components.Authorization
<AuthorizeView>
<Authorized>
<span class="nav-item">Hello, @context.User.Identity?.Name</span>
<form action="/authentication/logout" method="post" class="nav-item">
<AntiforgeryToken />
<input type="hidden" name="returnUrl" value="/" />
<button type="submit" class="btn btn-link nav-link">Logout</button>
</form>
</Authorized>
<NotAuthorized>
<a href="/authentication/login?returnUrl=/" class="nav-link">Login</a>
</NotAuthorized>
</AuthorizeView>
Toevoegen aan indeling: Integreer <UserInfo /> in uw MainLayout.razor:
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<UserInfo />
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
Routes.razor bijwerken voor AuthorizeRouteView
Vervangen RouteView door AuthorizeRouteView in Components/Routes.razor:
@using Microsoft.AspNetCore.Components.Authorization
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
<p>You are not authorized to view this page.</p>
<a href="/authentication/login">Login</a>
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
Uitzonderingen verwerken op pagina's die API's aanroepen
Blazor Server vereist expliciete afhandeling van uitzonderingen voor voorwaardelijke toegang en toestemming. U moet MicrosoftIdentityWebChallengeUserException verwerken op elke pagina die een downstream-API aanroept, tenzij uw app vooraf is geverifieerd en u alle scopes van tevoren aanvraagt in Program.cs.
In het volgende Weather.razor voorbeeld ziet u de juiste afhandeling van uitzonderingen:
@page "/weather"
@attribute [Authorize]
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Identity.Web
@inject WeatherApiClient WeatherApi
@inject BlazorAuthenticationChallengeHandler ChallengeHandler
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-warning">@errorMessage</div>
}
else if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
private string? errorMessage;
protected override async Task OnInitializedAsync()
{
if (!await ChallengeHandler.IsAuthenticatedAsync())
{
await ChallengeHandler.ChallengeUserWithConfiguredScopesAsync("WeatherApi:Scopes");
return;
}
try
{
forecasts = await WeatherApi.GetWeatherAsync();
}
catch (Exception ex)
{
// Handle incremental consent / Conditional Access
if (!await ChallengeHandler.HandleExceptionAsync(ex))
{
errorMessage = $"Error loading weather data: {ex.Message}";
}
}
}
}
Het patroon werkt als volgt:
-
IsAuthenticatedAsync()controleert of de gebruiker is aangemeld voordat de API-aanroepen worden uitgevoerd. -
HandleExceptionAsync()vangtMicrosoftIdentityWebChallengeUserException(of als InnerException). - Als het een challenge-exceptie is, wordt de gebruiker omgeleid om opnieuw te verifiëren met de vereiste claims of scopes.
- Als het geen uitzondering op een uitdaging is, retourneert
HandleExceptionAsyncfalsezodat u de fout zelf kunt afhandelen.
Clientgeheim opslaan in gebruikersgeheimen
Gebruik de .NET Secret Manager om het clientgeheim veilig op te slaan tijdens de ontwikkeling.
Waarschuwing
Voer nooit geheimen door aan broncodebeheer.
Initialiseer gebruikersgeheimen en sla het clientgeheim op:
cd MyService.Web
dotnet user-secrets init
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "<your-client-secret>"
Update dan appsettings.json om het hardcoded geheim te verwijderen.
{
"AzureAd": {
"ClientCredentials": [
{
"SourceType": "ClientSecret"
}
]
}
}
Microsoft. Identity.Web ondersteunt meerdere referentietypen. Zie referentieoverzicht voor productie.
De implementatie controleren
Gebruik deze controlelijst om te bevestigen dat u alle vereiste stappen hebt voltooid.
API-project
- [ ]
Microsoft.Identity.Web-pakket toegevoegd - [ ] Bijgewerkt
appsettings.jsonmetAzureAdsectie - [ ] Bijgewerkt
Program.csmetAddMicrosoftIdentityWebApi - [ ] Toegevoegd
.RequireAuthorization()aan beveiligde eindpunten
Web/Blazor-project
- [ ] Toegevoegd
Microsoft.Identity.Web-pakket (v3.3.0+) - [ ] Bijgewerkt
appsettings.jsonmet de sectiesAzureAdenWeatherApi - [ ] Bijgewerkt
Program.csmet OIDC, tokenverwerking - [ ] Toegevoegd
AddScoped<BlazorAuthenticationChallengeHandler>() - [ ] Aangemaakt
Components/UserInfo.razor(de login-knop) - [ ]
MainLayout.razorbijgewerkt om<UserInfo />op te nemen. - [ ] Bijgewerkt
Routes.razormetAuthorizeRouteView - [ ] Try/catch met
ChallengeHandlertoegevoegd op elke pagina die API's aanroept - [ ] Clientgeheim opgeslagen in gebruikersgeheimen
Verificatie
- [ ]
dotnet buildslaagt - [ ] App-registraties gemaakt in het Microsoft Entra-beheercentrum
- [ ]
appsettings.jsonheeft echte GUID's (geen tijdelijke aanduidingen)
Testen en problemen oplossen
Nadat u de implementatie hebt voltooid, voert u de toepassing uit en controleert u de end-to-end-verificatiestroom.
De toepassing uitvoeren
Start de Aspire AppHost om zowel de web- als API-projecten te starten:
# From solution root
dotnet restore
dotnet build
# Launch AppHost (starts both Web and API)
dotnet run --project .\MyService.AppHost\MyService.AppHost.csproj
De verificatiestroom testen
- Open de browser → Blazor Web UI (controleer het Aspire-dashboard op URL).
- Selecteer Login → Meld u aan met Microsoft Entra.
- Navigeer naar de pagina Weer .
- Controleer of de weergegevens geladen worden (van een beveiligde API).
Algemene problemen oplossen
De volgende tabel bevat veelvoorkomende problemen en de bijbehorende oplossingen:
| Issue | Solution |
|---|---|
| 401 bij API-aanroepen | Bereiken controleren in appsettings.json overeenstemming met de app-id-URI van de API |
| OIDC-omleiding mislukt | Voeg /signin-oidc toe aan de Microsoft Entra-omleidings-URI |
| Token niet gekoppeld | Zorg ervoor dat AddMicrosoftIdentityMessageHandler wordt aangeroepen op de HttpClient |
| Servicedetectie mislukt | Controleer AppHost.cs verwijzingen naar beide projecten en zorg dat ze actief zijn. |
| AADSTS65001 | Beheerderstoestemming vereist: toestemming verlenen in de Microsoft Entra-beheercentrum |
| Geen aanmeldingsknop | Controleren of UserInfo.razor deze bestaat en is opgenomen in MainLayout.razor |
| Toestemmingslus | Zorg ervoor dat try/catch met HandleExceptionAsync aanwezig is op alle pagina's voor API-aanroepen. |
MSAL-logboekregistratie inschakelen
Bij het oplossen van verificatieproblemen schakelt u gedetailleerde MSAL-logboekregistratie in om details van tokenovername te bekijken. Voeg de volgende logboekniveaus toe aan appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Identity": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Waarschuwing
Schakel logboekregistratie voor foutopsporing in productie uit omdat dit zeer uitgebreid kan zijn.
Tokens inspecteren
Als u tokenproblemen wilt opsporen, decodert u uw JWT op jwt.ms en controleert u het volgende:
-
aud(doelgroep): komt overeen met de client-id of app-id-URI van uw API -
iss(uitgever): komt overeen met uw tenant (https://login.microsoftonline.com/<tenant-id>/v2.0) -
scp(scopes): bevat de vereiste scopes -
exp(vervaldatum): token is niet verlopen
Algemene scenario's verkennen
In de volgende secties ziet u hoe u de basis-implementatie kunt uitbreiden voor aanvullende gebruiksvoorbeelden.
Blazor-pagina's beveiligen
Voeg het [Authorize] kenmerk toe aan pagina's waarvoor verificatie is vereist:
@page "/weather"
@attribute [Authorize]
Of definieer autorisatiebeleid in Program.cs:
// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
@attribute [Authorize(Policy = "AdminOnly")]
Bereiken valideren in de API
Zorg ervoor dat de API alleen tokens met specifieke rechten accepteert door deze te koppelen met RequireScope.
app.MapGet("/weatherforecast", () =>
{
// ... implementation
})
.RequireAuthorization()
.RequireScope("access_as_user");
App-alleen-tokens gebruiken (service-naar-service)
Voor daemon-scenario's of service-naar-service-aanroepen zonder gebruikerscontext, ingesteld RequestAppToken op true:
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
client.BaseAddress = new("https+http://apiservice");
})
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
options.RequestAppToken = true;
});
Certificaatloze referenties gebruiken voor productie
Gebruik voor productie-implementaties in Azure beheerde identiteit in plaats van clientgeheimen. Configureer de ClientCredentials sectie als volgt:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-guid>",
"ClientId": "<web-app-client-id>",
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity",
"ManagedIdentityClientId": "<user-assigned-mi-client-id>"
}
]
}
}
Zie Verificatie zonder certificaat voor meer informatie.
Downstream-API's aanroepen vanuit de API (namens een ander)
Als uw API namens de gebruiker een andere downstream-API moet aanroepen, schakelt u het verkrijgen van tokens namens de gebruiker in via Program.cs.
// MyService.ApiService/Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddDownstreamApi("GraphApi", builder.Configuration.GetSection("GraphApi"));
Voeg de downstream-API-configuratie toe aan appsettings.json:
{
"GraphApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": [ "User.Read" ]
}
}
Roep vervolgens de downstream-API aan vanaf een eindpunt:
{
var user = await downstreamApi.GetForUserAsync<JsonElement>("GraphApi", "me");
return user;
}).RequireAuthorization();
Zie Downstream-API's aanroepen voor meer informatie.