Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Leitfaden wird gezeigt, wie Sie eine .NET Aspire verteilte Anwendung mit Microsoft Entra ID Authentifizierung und Autorisierung sichern. Es umfasst:
-
Blazor Server frontend (
MyService.Web): Benutzeranmeldung mit OpenID Connect und Tokenerwerb -
Protected API-Backend (
MyService.ApiService): JWT-Überprüfung mit Microsoft.Identity.Web - End-to-End-Flow: Blazor erwirbt Zugriffstoken und ruft die geschützte API mit der Aspire-Dienstermittlung auf.
In diesem Leitfaden wird davon ausgegangen, dass Sie mit einem Aspire-Projekt begonnen haben, das mit dem folgenden Befehl erstellt wurde:
aspire new aspire-starter --name MyService
Voraussetzungen
- .NET 9 SDK oder höher
- .NET Aspire CLI - Siehe Install Aspire CLI
- Microsoft Entra Mandant – Informationen zum Einrichten finden Sie unter Anwendungen in Microsoft Entra ID registrieren
Tipp
Neu bei Aspire? Siehe .NET Aspire Overview.
Grundlegendes zum zweistufigen Workflow
Dieser Leitfaden folgt einem zweistufigen Ansatz:
| Phase | Was ist los | Ergebnis |
|---|---|---|
| Phase 1 | Hinzufügen von Authentifizierungscode mit Platzhalterwerten | App wird erstellt, aber nicht gestartet |
| Phase 2 | Bereitstellen Microsoft Entra App-Registrierungen | App wird mit echter Authentifizierung ausgeführt |
Registrieren von Apps in Microsoft Entra ID
Bevor Ihre App Benutzer authentifizieren kann, benötigen Sie zwei App-Registrierungen in Microsoft Entra:
| App-Registrierung | Purpose | Schlüsselkonfiguration |
|---|---|---|
API (MyService.ApiService) |
Überprüft eingehende Token | App-ID-URI, access_as_user Bereich |
Web App (MyService.Web) |
Anmeldung von Benutzern, Erwerb von Tokens | Umleitungs-URIs, geheimer Clientschlüssel, API-Berechtigungen |
Wenn Sie bereits App-Registrierungen konfiguriert haben, benötigen Sie diese Werte für Folgendes appsettings.json:
- TenantId – Ihre Microsoft Entra Mandanten-ID
- API-ClientId – Anwendungs-ID (Client) Ihrer API-App-Registrierung
-
API-App-ID-URI – In der Regel
api://<api-client-id>(verwendet inAudiencesundScopes) - Web App ClientId – Anwendungs-ID (Client) Ihrer Web-App-Registrierung
- Clientgeheimnis (oder Zertifikat) – Berechtigungsnachweis für die Webanwendung (in Benutzergeheimnissen speichern, nicht in appsettings.json)
-
Bereiche – Die Bereiche, die Ihre Web-App anfordert, z. B.
api://<api-client-id>/.defaultoderapi://<api-client-id>/access_as_user
Schritt 1: Registrieren der API
- Wechseln Sie zu Microsoft Entra Admin Center>Identity>Applications>App-Registrierungen.
- Wählen Sie Neue Registrierung aus.
-
Name:
MyService.ApiService - Unterstützte Kontotypen: Nur Konten in diesem Organisationsverzeichnis (einzelner Mandant)
- Wählen Sie Registrieren aus.
-
Name:
- Wechseln Sie zu Expose an API>Hinzufügen neben der Anwendungs-ID-URI.
- Übernehmen Sie die Standardeinstellung (
api://<client-id>) oder passen Sie sie an. - Wählen Sie "Bereich hinzufügen" aus:
-
Bereichsname:
access_as_user - Wer kann zustimmen: Administratoren und Benutzer
- Anzeigename der Administratorzustimmung: Zugreifen auf myService-API
- Beschreibung der Administratorzustimmung: Ermöglicht der App den Zugriff auf die MyService-API im Namen des angemeldeten Benutzers.
- Wählen Sie "Bereich hinzufügen" aus.
-
Bereichsname:
- Übernehmen Sie die Standardeinstellung (
- Kopieren Sie die Anwendungs-ID (Client-ID). Sie benötigen dies für beide
appsettings.jsonDateien.
Weitere Informationen finden Sie in der Schnellstartanleitung: Konfigurieren einer App zum Verfügbarmachen einer Web-API.
Schritt 2: Registrieren der Web-App
- Wechseln Sie zu App-Registrierungen>Neue Registrierung.
-
Name:
MyService.Web - Unterstützte Kontotypen: Nur Konten in diesem Organisationsverzeichnis
-
Umleitungs-URI: Wählen Sie "Web" aus, und geben Sie die URL Ihrer App ein+
/signin-oidc- Für die lokale Entwicklung:
https://localhost:7001/signin-oidc(Überprüfen Sie denlaunchSettings.jsontatsächlichen Port)
- Für die lokale Entwicklung:
- Wählen Sie Registrieren aus.
-
Name:
- Wechseln Sie zu Authentifizierung>URI hinzufügen, um alle Ihre Entwicklungs-URLs (von
launchSettings.json) hinzuzufügen. - Wechseln Sie zu Zertifikate und Geheimnisse>Clientgeheimnisse>Neues Clientgeheimnis.
- Fügen Sie eine Beschreibung und eine Ablauffrist hinzu.
- Kopieren Sie den geheimen Wert sofort, und es wird nicht mehr angezeigt.
- Wechseln Sie zu API-Berechtigungen> "Meine APIs hinzufügen>.
- Wähle
MyService.ApiServiceaus. - Wählen Sie
access_as_user>"Berechtigungen hinzufügen" aus. - Wählen Sie "Administratorzustimmung für [Mandant] erteilen" (oder Benutzer werden beim ersten Gebrauch aufgefordert).
- Wähle
- Kopieren Sie die Anwendungs-ID (Client-ID) für die Web-App.
appsettings.json
Hinweis
Einige Organisationen lassen geheime Clientschlüssel nicht zu. Alternativen finden Sie unter Zertifikatanmeldeinformationen oder zertifikatlose Authentifizierung.
Weitere Informationen finden Sie in der Schnellstartanleitung: Registrieren einer Anwendung.
Schritt 3: Aktualisieren der Konfiguration
Aktualisieren Sie nach dem Erstellen der App-Registrierungen Ihre appsettings.json Dateien:
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"]
}
}
Speichern Sie den geheimen Schlüssel sicher:
cd MyService.Web
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "YOUR_SECRET_VALUE"
| Wert | Wo finde ich |
|---|---|
TenantId |
Microsoft Entra Admin Center > Übersicht > Mandanten-ID |
API ClientId |
App-Registrierungen > MyService.ApiService > Anwendung (Client)-ID |
Web ClientId |
App-Registrierungen > MyService.Web > Anwendung (Client) ID |
Client Secret |
Erstellt in Schritt 2 (sofort kopieren, wenn erstellt) |
Hinweis
Die Aspire-Startvorlage erstellt automatisch eine WeatherApiClient Klasse im MyService.Web Projekt. Dieser typierte HttpClient wird in diesem Handbuch verwendet, um das Aufrufen der geschützten API zu veranschaulichen. Sie müssen diese Klasse nicht selbst erstellen – es ist Teil der Vorlage.
Schneller Einstieg
Dieser Abschnitt enthält einen komprimierten Verweis zum Hinzufügen der Authentifizierung. Ausführliche exemplarische Vorgehensweisen finden Sie in Teil 1 und Teil 2.
API (MyService.ApiService)
Installieren Sie das Microsoft.Identity.Web-NuGet-Paket
dotnet add package Microsoft.Identity.Web
Fügen Sie die Microsoft Entra-Konfiguration zu appsettings.json hinzu:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id>",
"ClientId": "<api-client-id>",
"Audiences": ["api://<api-client-id>"]
}
}
Registriere die Authentifizierung und Autorisierung 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)
Installieren Sie das Microsoft.Identity.Web NuGet-Paket.
dotnet add package Microsoft.Identity.Web
Fügen Sie die Microsoft Entra-Konfiguration zu appsettings.json hinzu:
{
"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"] }
}
Konfigurieren der Authentifizierung, des Tokenerwerbs und des nachgeschalteten API-Clients 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();
Der MicrosoftIdentityMessageHandler erwirbt und fügt automatisch Token an, und BlazorAuthenticationChallengeHandler verarbeitet Zustimmungs- und bedingte Zugriff-Herausforderungen.
Von Bedeutung
Vergessen Sie nicht, UserInfo.razor für die Anmeldeschaltfläche zu erstellen. Weitere Informationen finden Sie unter "Blazor UI-Komponenten hinzufügen ".
Hinweis
BlazorAuthenticationChallengeHandler und LoginLogoutEndpointRouteBuilderExtensions sind Bestandteil von Microsoft.Identity.Web (v3.3.0+). Es ist kein Kopieren von Dateien erforderlich.
Identifizieren der zu ändernden Dateien
In der folgenden Tabelle sind die Dateien aufgeführt, die Sie in den einzelnen Projekten ändern:
| Project | Datei | Änderungen |
|---|---|---|
| ApiService | Program.cs |
JWT Bearer Authentifizierung, Autorisierungs-Middleware |
appsettings.json |
Microsoft Entra-Konfiguration | |
.csproj |
Hinzufügen von Microsoft.Identity.Web |
|
| Web | Program.cs |
OIDC-Authentifizierung, Tokenerwerb, BlazorAuthenticationChallengeHandler |
appsettings.json |
Microsoft Entra Konfiguration, nachgeschaltete API-Bereiche | |
.csproj |
Hinzufügen von Microsoft.Identity.Web (v3.3.0+) |
|
Components/UserInfo.razor |
UI des Login-Buttons (neue Datei) | |
Components/Layout/MainLayout.razor |
UserInfo-Komponente einschließen | |
Components/Routes.razor |
AuthorizeRouteView für geschützte Seiten | |
| Seiten, die APIs aufrufen | "Try/Catch mit Challenge-Handler" |
Grundlegendes zum Authentifizierungsfluss
Das folgende Diagramm zeigt, wie das Blazor-Frontend, Microsoft Entra und die geschützte API interagieren:
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
- Der Benutzer besucht blazor-App → Nicht authentifiziert → sieht die Schaltfläche "Anmelden".
-
Benutzer wählt "Login" → Leitet zu
/authentication/login→ OIDC-Herausforderung → Microsoft Entra um. -
User meldet sich an → Microsoft Entra leitet weiter zu
/signin-oidc→ Cookie eingerichtet. -
Der Benutzer navigiert zur Wetterseite → Blazor ruft
WeatherApiClient.GetAsync()auf. -
MicrosoftIdentityMessageHandlerfängt die Anforderung ab, erwirbt ein Token aus dem Cache (oder aktualisiert es stillschweigend im Hintergrund) und fügt denAuthorization: Bearer <token>Header an. - API empfängt Anforderung → Microsoft.Identity.Web validiert das JWT → gibt Daten zurück.
- Blazor rendert Wetterdaten.
Überprüfen der Lösungsstruktur
Die Projektstartvorlage "Aspire" erstellt das folgende Projektlayout:
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
Teil 1: Sichern des API-Back-Ends mit Microsoft. Identity.Web
In diesem Abschnitt wird das API-Projekt so konfiguriert, dass von Microsoft Entra ausgestellte JWT Bearer-Token überprüft werden.
Fügen Sie das Paket Microsoft.Identity.Web hinzu
Führen Sie den folgenden Befehl aus, um das Microsoft.Identity.Web-NuGet-Paket zu installieren:
cd MyService.ApiService
dotnet add package Microsoft.Identity.Web
Konfigurieren von Microsoft Entra-Einstellungen
Fügen Sie die Microsoft Entra-Konfiguration zu MyService.ApiService/appsettings.json hinzu:
{
"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": "*"
}
Wichtige Eigenschaften:
-
ClientId: Microsoft Entra API-App-Registrierungs-ID -
TenantId: Ihre Microsoft Entra-Mandanten-ID,"organizations"für mehrere Mandanten oder"common"für alle Microsoft-Konten -
Audiences: Gültige Token-Zielgruppen (in der Regel Ihre App-ID-URI)
API-Program.cs Aktualisieren
Ersetzen Sie den Inhalt von MyService.ApiService/Program.cs durch den folgenden Code, um JWT-Bearer-Authentifizierung hinzuzufügen und Endpunkte zu schützen:
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);
}
Wichtige Änderungen:
- JWT Bearer-Authentifizierung mit
AddMicrosoftIdentityWebApiregistrieren - Hinzufügen von
app.UseAuthentication()undapp.UseAuthorization()Middleware - Anwenden
.RequireAuthorization()auf geschützte Endpunkte
Testen der geschützten API
Überprüfen Sie, ob die API nicht authentifizierte Anforderungen ablehnt und gültige Token akzeptiert.
Senden einer Anforderung ohne Token:
curl https://localhost:<PORT>/weatherforecast
# Expected: 401 Unauthorized
Senden einer Anforderung mit einem gültigen Token:
curl -H "Authorization: Bearer <TOKEN>" https://localhost:<PORT>/weatherforecast
# Expected: 200 OK with weather data
Teil 2: Konfigurieren des Blazor-Frontends für die Authentifizierung
Die Blazor Server-App verwendet Microsoft. Identity.Web für:
- Anmelden von Benutzern mit OIDC
- Abrufen von Zugriffstoken zum Aufrufen der API
- Token an ausgehende HTTP-Anforderungen anfügen
Fügen Sie das Paket Microsoft.Identity.Web hinzu
Führen Sie den folgenden Befehl aus, um das Microsoft.Identity.Web-NuGet-Paket zu installieren:
cd MyService.Web
dotnet add package Microsoft.Identity.Web
Konfigurieren von Microsoft Entra-Einstellungen
Fügen Sie Microsoft Entra Konfigurations- und downstream-API-Bereiche zu MyService.Web/appsettings.json hinzu:
{
"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": "*"
}
Konfigurationsdetails:
-
ClientId: Web App-Registrierungs-ID (nicht die API-ID) -
ClientCredentials: Anmeldeinformationen für die Web-App zum Abrufen von Token. Unterstützt mehrere Anmeldeinformationstypen. Unter "Anmeldeinformationen" finden Sie eine Übersicht über produktionsfähige Optionen. -
Scopes: Muss mit dem App-ID-URI der API mit/.defaultsuffix übereinstimmen
Warnung
Verwenden Sie für die Produktion Zertifikate oder verwaltete Identitäten anstelle von geheimen Clientschlüsseln. Siehe Zertifikatlose Authentifizierung für den empfohlenen Ansatz.
Web-App-Program.cs aktualisieren
Ersetzen Sie den Inhalt von MyService.Web/Program.cs durch den folgenden Code, um die OIDC-Authentifizierung, den Tokenerwerb und den Downstream-API-Client zu konfigurieren:
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();
Wichtige Punkte:
-
AddMicrosoftIdentityWebApp: Konfiguriert die OIDC-Authentifizierung -
EnableTokenAcquisitionToCallDownstreamApi: Aktiviert die Tokenerfassung für nachgeschaltete APIs -
AddScoped<BlazorAuthenticationChallengeHandler>: Verarbeitet inkrementelle Zustimmung und bedingten Zugriff in Blazor Server -
AddMicrosoftIdentityMessageHandler: Fügt Bearertoken automatisch an HttpClient-Anforderungen an -
https+http://apiservice: Aspire Service Discovery löst dies in die tatsächliche API-URL auf. -
Middleware-Reihenfolge:
UseAuthentication()→UseAuthorization()→ Endpunkte
Die AddMicrosoftIdentityMessageHandler Erweiterung unterstützt mehrere Konfigurationsmuster:
Option 1: Konfiguration von appsettings.json (siehe vorherige Darstellung)
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
Option 2: Inlinekonfiguration mit Aktionsdelegat
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
});
Option 3: Konfiguration pro Anforderung (parameterlos)
.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);
Hinzufügen von Blazor-UI-Komponenten
Von Bedeutung
Dieser Schritt wird häufig vergessen. Ohne die UserInfo-Komponente haben Benutzer keine Möglichkeit, sich anzumelden.
BlazorAuthenticationChallengeHandler und LoginLogoutEndpointRouteBuilderExtensions sind in Microsoft.Identity.Web v3.3.0+ verfügbar. Sie sind automatisch verfügbar, sobald Sie auf das Paket verweisen . Es ist kein Dateikopiervorgang erforderlich.
Erstellen: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>
Zum Layout hinzufügen: Fügen Sie <UserInfo /> in Ihr MainLayout.razor ein:
@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>
Aktualisieren von Routes.razor für AuthorizeRouteView
Ersetzen Sie RouteView durch 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>
Behandeln von Ausnahmen auf Seiten, die APIs aufrufen
Blazor Server erfordert eine explizite Ausnahmebehandlung für bedingten Zugriff und die Zustimmung. Sie müssen auf jeder Seite, die eine Downstream-API aufruft, MicrosoftIdentityWebChallengeUserException behandeln, es sei denn, Ihre App ist vorautorisiert, und Sie fordern alle Berechtigungen im Voraus in Program.cs an.
Im folgenden Weather.razor Beispiel wird die ordnungsgemäße Ausnahmebehandlung veranschaulicht:
@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}";
}
}
}
}
Das Muster funktioniert wie folgt:
-
IsAuthenticatedAsync()überprüft, ob der Benutzer angemeldet ist, bevor API-Aufrufe ausgeführt werden. -
HandleExceptionAsync()CatchesMicrosoftIdentityWebChallengeUserException(oder als InnerException). - Wenn es sich um eine Herausforderungsausnahme handelt, wird der Benutzer zur erneuten Authentifizierung mit den erforderlichen Ansprüchen oder Scopes umgeleitet.
- Wenn es sich nicht um eine Ausnahme bei der Herausforderung handelt, wird
HandleExceptionAsynczurückgegeben,falsedamit Sie den Fehler selbst behandeln können.
Speichern des Client Secret in Benutzergeheimnissen
Verwenden Sie den .NET Geheimen Manager, um den geheimen Clientschlüssel während der Entwicklung sicher zu speichern.
Vorsicht
Übernehmen Sie niemals geheime Schlüssel zur Quellcodeverwaltung.
Initialisieren Sie Benutzergeheimnisse, und speichern Sie den geheimen Clientschlüssel.
cd MyService.Web
dotnet user-secrets init
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "<your-client-secret>"
Aktualisieren Sie appsettings.json dann, um den hartcodierten geheimen Schlüssel zu entfernen:
{
"AzureAd": {
"ClientCredentials": [
{
"SourceType": "ClientSecret"
}
]
}
}
Microsoft. Identity.Web unterstützt mehrere Anmeldeinformationstypen. Informationen zur Produktion finden Sie in der Übersicht zu den Zugangsdaten.
Überprüfen der Implementierung
Verwenden Sie diese Checkliste, um zu bestätigen, dass Sie alle erforderlichen Schritte ausgeführt haben.
API-Projekt
- [ ] Paket
Microsoft.Identity.Webhinzugefügt - [ ] Aktualisiert
appsettings.jsonmit AbschnittAzureAd - [ ] Aktualisiert
Program.csmitAddMicrosoftIdentityWebApi - [ ] Zu geschützten Endpunkten hinzugefügt
.RequireAuthorization()
Web/Blazor-Projekt
- [ ] Paket
Microsoft.Identity.Webhinzugefügt (v3.3.0+) - [ ] Aktualisiert
appsettings.jsonmit den AbschnittenAzureAdundWeatherApi - [ ] Aktualisiert
Program.csmit OIDC, Token-Erwerb - [ ] Hinzugefügt
AddScoped<BlazorAuthenticationChallengeHandler>() - [ ] Erstellt
Components/UserInfo.razor(die Anmeldeschaltfläche) - [ ] Aktualisiert
MainLayout.razor, um einzuschließen<UserInfo /> - [ ] Aktualisiert
Routes.razormitAuthorizeRouteView - [ ] Try/Catch-Anweisungen mit
ChallengeHandlerzu jedem Seitenaufruf von APIs hinzugefügt - [ ] Gespeichertes Client-Geheimnis in Benutzergeheimnissen
Verifizierung
- [ ]
dotnet buildist erfolgreich - [ ] App-Registrierungen im Microsoft Entra Admin Center erstellt
- [ ]
appsettings.jsonverfügt über echte GUIDs (keine Platzhalter)
Testen und Problembehandlung
Nachdem Sie die Implementierung abgeschlossen haben, führen Sie die Anwendung aus, und überprüfen Sie den End-to-End-Authentifizierungsfluss.
Ausführen der Anwendung
Starten Sie den Aspire AppHost, um sowohl web- als auch API-Projekte zu starten:
# From solution root
dotnet restore
dotnet build
# Launch AppHost (starts both Web and API)
dotnet run --project .\MyService.AppHost\MyService.AppHost.csproj
Testen des Authentifizierungsflusses
- Öffnen Sie browser → Blazor Web UI (überprüfen Sie das Aspire-Dashboard auf URL).
- Wählen Sie Login → Melden Sie sich mit Microsoft Entra an.
- Navigieren Sie zur Wetterseite .
- Überprüfen sie, ob Wetterdaten geladen werden (aus geschützter API).
Allgemeine Probleme beheben
In der folgenden Tabelle sind häufige Probleme und deren Lösungen aufgeführt:
| Thema | Lösung |
|---|---|
| 401 für API-Aufrufe | Überprüfen Sie, ob die Bereiche in appsettings.json mit dem App-ID-URI der API übereinstimmen. |
| Fehler bei der OIDC-Umleitung | Fügen Sie /signin-oidc zu Microsoft Entra Umleitungs-URIs hinzu |
| Token nicht angehängt | Sicherstellen, dass AddMicrosoftIdentityMessageHandler auf HttpClient aufgerufen wird |
| Service Discovery fehlgeschlagen | Überprüfen Sie, ob AppHost.cs sich auf beide Projekte bezieht und diese ausgeführt werden |
| AADSTS65001 | Administratorzustimmung erforderlich – Erteilen der Zustimmung im Microsoft Entra Admin Center |
| Keine Anmeldeschaltfläche | Sicherstellen, dass UserInfo.razor vorhanden ist und in MainLayout.razor enthalten ist |
| Zustimmungsschleife | Stellen Sie sicher, dass try/catch HandleExceptionAsync auf allen API aufrufenden Seiten enthalten ist |
Aktivieren der MSAL-Protokollierung
Aktivieren Sie bei Authentifizierungsproblemen die detaillierte MSAL-Protokollierung, um Details zum Tokenerwerb anzuzeigen. Fügen Sie die folgenden Protokollebenen hinzu:appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Identity": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Warnung
Deaktivieren Sie die Debugprotokollierung in der Produktion, da sie sehr ausführlich sein kann.
Token prüfen
Um Tokenprobleme zu debuggen, decodieren Sie Ihr JWT bei jwt.ms , und überprüfen Sie Folgendes:
-
aud(audience): Entspricht der Client-ID oder dem App-ID-URI Ihrer API. -
iss(Aussteller): Entspricht Ihrem Mandanten (https://login.microsoftonline.com/<tenant-id>/v2.0) -
scp(Bereiche): Enthält die erforderlichen Bereiche. -
exp(Ablauf): Das Token ist noch nicht abgelaufen.
Erkunden gängiger Szenarien
In den folgenden Abschnitten wird gezeigt, wie Sie die Basisimplementierung für zusätzliche Anwendungsfälle erweitern.
Schützen von Blazor-Seiten
Fügen Sie das [Authorize] Attribut zu Seiten hinzu, die eine Authentifizierung erfordern:
@page "/weather"
@attribute [Authorize]
Oder definieren Sie Autorisierungsrichtlinien in Program.cs:
// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
@attribute [Authorize(Policy = "AdminOnly")]
Überprüfen der Gültigkeitsbereiche in der API
Stellen Sie sicher, dass die API nur Token mit bestimmten Bereichen akzeptiert, indem Sie verketten RequireScope:
app.MapGet("/weatherforecast", () =>
{
// ... implementation
})
.RequireAuthorization()
.RequireScope("access_as_user");
Verwendung von App-only-Token (Dienst-zu-Dienst)
Legen Sie für Daemon-Szenarien oder Dienst-zu-Dienst-Aufrufe ohne Benutzerkontext RequestAppToken auf 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;
});
Verwenden von zertifikatlosen Anmeldeinformationen für die Produktion
Verwenden Sie für Produktionsbereitstellungen in Azure verwaltete Identität anstelle von geheimen Clientschlüsseln. Konfigurieren Sie den ClientCredentials Abschnitt wie folgt:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-guid>",
"ClientId": "<web-app-client-id>",
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity",
"ManagedIdentityClientId": "<user-assigned-mi-client-id>"
}
]
}
}
Weitere Informationen finden Sie unter Zertifikatlose Authentifizierung.
Aufruf nachgeschalteter APIs durch die API (im Namen von)
Wenn Ihre API eine andere nachgelagerte API im Auftrag des Benutzers aufrufen muss, aktivieren Sie den Erwerb von Token im Auftrag des Benutzers in 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"));
Fügen Sie die Downstream-API-Konfiguration zu appsettings.json hinzu.
{
"GraphApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": [ "User.Read" ]
}
}
Rufen Sie dann die downstream-API von einem Endpunkt auf:
{
var user = await downstreamApi.GetForUserAsync<JsonElement>("GraphApi", "me");
return user;
}).RequireAuthorization();
Weitere Informationen finden Sie unter Aufrufen von downstream-APIs.