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.
Note
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Dieser Artikel beschreibt, wie man eine Blazor Web App mit OpenID Connect (OIDC) anhand einer Beispiel-App im dotnet/blazor-samples GitHub-Repository (.NET 8 oder höher) sichert (Hinweis zum Download).
Für Microsoft Entra ID oder Azure AD B2C können Sie AddMicrosoftIdentityWebApp von Microsoft Identity Web (Microsoft.Identity.Web, API-Dokumentation) verwenden, das sowohl die OIDC- als auch die Authentifizierungs-Handler mit den entsprechenden Standardwerten hinzufügt. Die Beispiel-App und die Anleitungen in diesem Artikel verwenden Microsoft Identity Web nicht. Die Anleitung veranschaulicht, wie der OIDC-Handler manuell für die einzelnen OIDC-Anbieter konfiguriert wird. Weitere Informationen zur Implementierung von Microsoft Identity Web finden Sie unter Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID.
Diese Version des Artikels behandelt die Implementierung von OIDC, ohne das Back-End-für-Frontend- (BFF) Muster bei einer App zu verwenden, die globales interaktives Autorendering (Server- und .Client Projekte) verwendet. Das BFF-Muster ist nützlich, um authentifizierte Anforderungen an externe Dienste zu senden. Ändern Sie die Artikelversionsauswahl in BFF-Muster, wenn die App-Spezifikation aufruft, das BFF-Muster zu übernehmen.
Die folgende Spezifikation wird angenommen:
- Die Blazor Web App verwendet den automatischen Rendermodus mit globaler Interaktivität.
- Benutzerdefinierte Dienste für Authentifizierungsstatusanbieter werden von Server- und Client-Apps verwendet, um den Authentifizierungsstatus von Benutzern bzw. Benutzerinnen zu erfassen und zwischen Server und Client zu übertragen.
- Diese App ist ein Ausgangspunkt für jeden OIDC-Authentifizierungsflow. OIDC wird manuell in der App konfiguriert und ist nicht auf Microsoft Entra ID oder Microsoft Identity Web-Pakete angewiesen, und die Beispiel-App erfordert kein Microsoft Azure-Hosting. Die Beispiel-App kann jedoch mit Entra und Microsoft Identity Web verwendet und in Azure gehostet werden.
- Automatische nicht interaktive Tokenaktualisierung
- Ein separates Web-API-Projekt veranschaulicht einen sicheren Web-API-Aufruf für Wetterdaten.
Eine alternative Erfahrung mit Microsoft Authentication Library for .NET, Microsoft Identity Web und Microsoft Entra ID finden Sie unter Sichern eines ASP.NET Core Blazor Web App mit Microsoft Entra ID.
Beispiellösung
Die Beispiel-App besteht aus den folgenden Projekten:
-
BlazorWebAppOidc: Serverseitiges Projekt des Blazor Web App, das einen Beispiel Minimal API-Endpunkt für Wetterdaten enthält. -
BlazorWebAppOidc.Client: Clientseitiges Projekt der Blazor Web App. -
MinimalApiJwt: Back-End-Web-API mit einem minimalen API-Endpunkt für Wetterdaten.
Greifen Sie auf das Beispiel über den neuesten Versionsordner im Repository für Blazor Beispiele mit dem folgenden Link zu. Das Beispiel befindet sich im Ordner BlazorWebAppOidc für .NET 8 oder höher.
Starten Sie die Lösung vom Aspire/Aspire.AppHost Projekt.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Merkmale der Musterlösung:
Automatische, nicht interaktive Tokenaktualisierung mithilfe eines benutzerdefinierten cookie-Aktualisierers (
CookieOidcRefresher.cs).Wetterdaten werden von einem minimalen API-Endpunkt (
/weather-forecast) in derProgramDatei (Program.cs) desMinimalApiJwtProjekts behandelt. Für den Endpunkt ist eine Autorisierung durch Aufruf von RequireAuthorizationerforderlich. Fügen Sie für alle Controller, die Sie dem Projekt hinzufügen, das[Authorize]-Attribut dem Controller oder der Aktion hinzu. Weitere Informationen dazu, wie Sie die Autorisierung in der gesamten App über eine Autorisierungsrichtlinie verlangen und die Autorisierung an einer Untermenge von öffentlichen Endpunkten ausschließen können, finden Sie in der RazorSeiten OIDC Anleitung.Die App ruft sicher eine Web-API für Wetterdaten auf:
- Beim Rendern der
WeatherKomponente auf dem Server verwendet die Komponente denServerWeatherForecasterauf dem Server, um Wetterdaten aus der Web-API imMinimalApiJwtProjekt abzurufen. Dies geschieht mithilfe eines DelegatingHandler (TokenHandler), der das Zugriffstoken von HttpContext an die Anfrage anfügt. - Wenn die Komponente auf dem Client gerendert wird, verwendet die Komponente die
ClientWeatherForecasterDienstimplementierung, die eine vorkonfigurierte HttpClient (in der Datei des ClientprojektsProgram) verwendet, um den Web-API-Aufruf des ServerprojektsServerWeatherForecasterdurchzuführen.
- Beim Rendern der
- Das Serverprojekt ruft AddAuthenticationStateSerialization auf, um einen serverseitigen Authentifizierungsstatusanbieter hinzuzufügen, der PersistentComponentState verwendet, um den Authentifizierungsstatus zum Client zu übertragen. Der Client ruft AddAuthenticationStateDeserialization auf, um den vom Server übergebenen Authentifizierungsstatus zu deserialisieren und zu verwenden. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
- Die Klasse
PersistingAuthenticationStateProvider(PersistingAuthenticationStateProvider.cs) ist ein serverseitiges AuthenticationStateProvider-Element, das PersistentComponentState verwendet, um den Authentifizierungsstatus an den Client zu senden, der dann für die Lebensdauer der WebAssembly-Anwendung festgelegt wird.
Weitere Informationen zu (Web-)API-Aufrufen unter Verwendung von Dienstabstraktionen in Blazor Web Apps finden Sie unter Aufruf einer Web-API von einer ASP.NET Core-Blazor-App.
Terminologie und Anleitungen für OIDC-Anbieter
Obwohl Sie Microsoft Entra (ME-ID) nicht als OIDC-Anbieter verwenden müssen, um die Beispiel-App und die Anleitungen in diesem Artikel zu verwenden, beschreibt dieser Artikel Einstellungen für ME-ID Verwenden von Namen, die in der Microsoft-Dokumentation und den Azure/Entra-Portalen zu finden sind. OIDC-Einstellungen weisen ähnliche Benennungen bei OIDC-Anbietern auf. Wenn Sie einen Drittanbieter für OIDC verwenden, verwenden Sie die Dokumentation des Anbieters in Verbindung mit den Anleitungen in diesem Artikel für App- und Web-API-Registrierungen.
Microsoft Entra ID-App-Registrierungen
Es wird empfohlen, separate Registrierungen für Apps und Web-APIs zu verwenden, auch wenn sich die Apps und Web-APIs in derselben Lösung befinden. Der folgende Leitfaden richtet sich an die BlazorWebAppOidc App- und MinimalApiJwt Web-API der Beispiellösung, gilt jedoch im Allgemeinen für alle Entra-basierten Registrierungen für Apps und Web-APIs.
Anleitungen zur App- und Web-API-Registrierung finden Sie unter Registrieren einer Anwendung in der Microsoft Entra-ID.
Registrieren Sie zuerst die Web-API (MinimalApiJwt), damit Sie beim Registrieren der App Zugriff auf die Web-API gewähren können. Die Mandanten-ID und Client-ID der Web-API werden verwendet, um die Web-API in ihrer Program Datei zu konfigurieren. Nachdem Sie die Web-API registriert haben, exponieren Sie die Web-API in App-Registrierungen>API exponieren mit einem Bereichsnamen von Weather.Get. Notieren Sie den App-ID-URI für die Verwendung in der App-Konfiguration.
Registrieren Sie als Nächstes die App (BlazorWebAppOidc/BlazorWebApOidc.Client) mit einer Webplattformkonfiguration und einem Umleitungs-URI von https://localhost/signin-oidc (ein Port ist nicht erforderlich). Die Mandanten-ID und die Client-ID der App werden zusammen mit Basisadresse der Web-API, App-ID-URI und Wetterbereichsnamen verwendet, um die App in ihrer Program-Datei zu konfigurieren. Erteilen Sie API-Berechtigungen zum Zugriff auf die Web-API unter App-Registrierungen>API-Berechtigungen. Wenn die Sicherheitsspezifikation der App dies aufruft, können Sie der Organisation die Zustimmung des Administrators für den Zugriff auf die Web-API erteilen. Autorisierte Benutzer und Gruppen werden der Registrierung der App in App-Registrierungen>Enterprise-Anwendungen zugewiesen.
Konfigurieren Sie in der Entra- oder Azure-Portal-Konfiguration der impliziten Genehmigung und hybriden Bewegungsarten der App-Registrierung, dass Sie kein Kontrollkästchen aktivieren, damit der Autorisierungsendpunkt keine Zugriffstoken oder ID-Token zurückgibt. Der OpenID Connect-Anforderungshandler fordert automatisch die entsprechenden Token an, indem er den vom Autorisierungsendpunkt zurückgegebenen Code verwendet.
Erstellen Sie ein Client-Geheimnis in der App-Registrierung im Entra- oder Azure-Portal (Verwalten>Zertifikate und Geheimnisse>neues Client-Geheimnis). Warten Sie auf den geheimen Clientschlüssel Wert zur Nutzung im nächsten Abschnitt.
Weitere Anleitungen zur Entra-Konfiguration für bestimmte Einstellungen finden Sie weiter unten in diesem Artikel.
Einrichten des geheimen Clientschlüssels
Dieser Abschnitt gilt nur für das Serverprojekt des Blazor Web App (BlazorWebAppOidc Projekts).
Warning
Speichern Sie keine geheimen App-Schlüssel, Verbindungszeichenfolge s, Anmeldeinformationen, Kennwörter, persönliche Identifikationsnummern (PINs), privaten C#/.NET-Code oder private Schlüssel/Token im clientseitigen Code, der immer unsicher ist. In Test-/Staging- und Produktionsumgebungen sollten serverseitiger Blazor Code und Web-APIs sichere Authentifizierungsflüsse verwenden, die vermeiden, Anmeldedaten im Projektcode oder in Konfigurationsdateien zu speichern. Außerhalb der lokalen Entwicklungstests wird empfohlen, die Verwendung von Umgebungsvariablen zum Speichern vertraulicher Daten zu vermeiden, da Umgebungsvariablen nicht der sicherste Ansatz sind. Für lokale Entwicklungstests wird das Tool "Geheimer Manager" zum Sichern vertraulicher Daten empfohlen. Weitere Informationen finden Sie unter "Sichere Verwaltung vertraulicher Daten und Anmeldeinformationen".
Verwenden Sie für lokale Entwicklungstests das Tool "Geheimer Manager ", um den geheimen Clientschlüssel des Blazor Serverprojekts unter dem Konfigurationsschlüssel Authentication:Schemes:MicrosoftOidc:ClientSecretzu speichern.
Das Blazor Serverprojekt wurde für das Tool "Geheimer Manager" nicht initialisiert. Verwenden Sie eine Befehlsshell, z. B. die PowerShell-Befehlsshell für Entwickler in Visual Studio, um den folgenden Befehl auszuführen. Ändern Sie vor dem Ausführen des Befehls das Verzeichnis mit dem cd Befehl in das Verzeichnis des Serverprojekts. Der Befehl richtet einen bezeichner für geheime Benutzerschlüssel ein (<UserSecretsId> in der Projektdatei der Server-App):
dotnet user-secrets init
Führen Sie den folgenden Befehl aus, um den geheimen Clientschlüssel festzulegen. Der {SECRET} Platzhalter ist der geheime Clientschlüssel, der aus der Registrierung der App abgerufen wird:
dotnet user-secrets set "Authentication:Schemes:MicrosoftOidc:ClientSecret" "{SECRET}"
Wenn Sie Visual Studio verwenden, können Sie bestätigen, dass der geheime Schlüssel festgelegt ist, indem Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Serverprojekt klicken und "Benutzergeheimnisse verwalten" auswählen.
MinimalApiJwt Projekt
Das Projekt MinimalApiJwt ist eine Back-End-Web-API für mehrere Front-End-Projekte. Das Projekt konfiguriert einen Endpunkt für die Minimal-API für Wetterdaten.
Die Datei MinimalApiJwt.http kann zum Testen der Wetterdatenanforderung verwendet werden. Beachten Sie, dass das MinimalApiJwt-Projekt ausgeführt werden muss, um den Endpunkt zu testen, wobei der Endpunkt in der Datei hartcodiert ist. Weitere Informationen finden Sie unter Verwenden von HTTP-Dateien in Visual Studio 2022.
Das Projekt enthält Pakete und Konfigurationen zum Erstellen von OpenAPI-Dokumenten.
Das Projekt enthält Pakete und Konfigurationen, um OpenAPI-Dokumente und die Swagger-UI in der Entwicklungsumgebung zu erstellen. Weitere Informationen finden Sie unter Verwenden der generierten OpenAPI-Dokumente.
Das Projekt erstellt einen minimalen API-Endpunkt für Wetterdaten:
app.MapGet("/weather-forecast", () =>
{
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;
}).RequireAuthorization();
Konfigurieren Sie das Projekt in den JwtBearerOptions des AddJwtBearer-Aufrufs in der Datei Program des Projekts.
Authority legt die Autorität für das Tätigen von OIDC-Aufrufen fest. Es wird empfohlen, eine separate App-Registrierung für das MinimalApiJwt Projekt zu verwenden. Die Autorität entspricht dem Aussteller (iss) des vom Identitätsanbieter zurückgegebenen JWT.
jwtOptions.Authority = "{AUTHORITY}";
Das Format der Autorität hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden die Mandanten-ID aaaabbbb-0000-cccc-1111-dddd2222eeee.
Beispiel für ME-ID-Mandantenautorität:
jwtOptions.Authority = "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee";
Beispiel für AAD B2C-Mandantenautorität:
jwtOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
Audience legt die Zielgruppe für empfangene OIDC-Token fest.
jwtOptions.Audience = "{APP ID URI}";
Note
Wenn Sie Microsoft Entra ID verwenden, stimmen Sie den Wert mit dem Pfad der Anwendungs-ID URI ab, die beim Hinzufügen des Weather.Get -Bereichs unter Expose an API im Entra- oder Azure-Portal konfiguriert wurde. Fügen Sie den Bereichsnamen "Weather.Get," nicht in den Wert ein.
Das Format der Zielgruppe hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden eine Mandanten-ID von contoso und eine Client-ID von 11112222-bbbb-3333-cccc-4444dddd5555.
Beispiel für die App-ID-URI des ME-ID-Mandanten:
jwtOptions.Audience = "api://11112222-bbbb-3333-cccc-4444dddd5555";
Beispiel für die App-ID-URI des AAD B2C-Mandanten:
jwtOptions.Audience = "https://contoso.onmicrosoft.com/11112222-bbbb-3333-cccc-4444dddd5555";
Blazor Web App Serverprojekt (BlazorWebAppOidc)
Das BlazorWebAppOidc-Projekt ist das serverseitige Projekt des Blazor Web App.
Ein DelegatingHandler (TokenHandler) verwaltet das Anfügen des Benutzerzugriffstokens an ausgehende Anforderungen. Der Tokenhandler wird nur während des statischen serverseitigen Renderings (statischer SSR) ausgeführt. Daher ist die Verwendung HttpContext in diesem Szenario sicher. Weitere Informationen finden Sie unter "IHttpContextAccessor/HttpContext" in ASP.NET Core-Apps Blazor und ASP.NET Core serverseitige und Blazor Web App zusätzliche Sicherheitsszenarien.
TokenHandler.cs:
public class TokenHandler(IHttpContextAccessor httpContextAccessor) :
DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (httpContextAccessor.HttpContext is null)
{
throw new Exception("HttpContext not available");
}
var accessToken = await httpContextAccessor.HttpContext
.GetTokenAsync("access_token");
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
return await base.SendAsync(request, cancellationToken);
}
}
In der Datei des Program-Projekts wird der Tokenhandler (TokenHandler) als Dienst registriert und als Nachrichtenhandler festgelegt, um mit AddHttpMessageHandler sichere Anforderungen an die Back-End-MinimalApiJwt-Web-API mithilfe eines benannten HTTP-Clients ("ExternalApi") zu stellen.
builder.Services.AddScoped<TokenHandler>();
builder.Services.AddHttpClient("ExternalApi",
client => client.BaseAddress = new Uri(builder.Configuration["ExternalApiUri"] ??
throw new Exception("Missing base address!")))
.AddHttpMessageHandler<TokenHandler>();
Konfigurieren Sie den URI der externen API in der appsettings.json-Datei des Projekts:
"ExternalApiUri": "{BASE ADDRESS}"
Example:
"ExternalApiUri": "https://localhost:7277"
Die folgende OpenIdConnectOptions-Konfiguration befindet sich in der Datei Program des Projekts beim Aufruf von AddOpenIdConnect:
PushedAuthorizationBehavior: Steuert den Pushed Authorization Requests (PAR)-Support. Standardmäßig ist die Einstellung so, dass PAR verwendet wird, wenn das Discovery-Dokument des Identitätsanbieters (normalerweise unter .well-known/openid-configuration) den Support für PAR ankündigt. Wenn Sie den PAR-Support für die App erwerben möchten, weisen Sie einen Wert von PushedAuthorizationBehavior.Require zu. PAR wird nicht von Microsoft Entra unterstützt und es gibt auch keine Pläne diesbezüglich für die Zukunft.
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.UseIfAvailable;
SignInScheme: Legt das Authentifizierungsschema fest, das der Middleware entspricht, die für die Beibehaltung der Identität von Benutzern bzw. Benutzerinnen nach einer erfolgreichen Authentifizierung verantwortlich ist. Der OIDC-Handler muss ein Anmeldeschema verwenden, das Benutzeranmeldeinformationen über Anforderungen hinweg beibehalten kann. Die folgende Zeile dient ist lediglich der Veranschaulichung. Wird sie weggelassen, wird DefaultSignInScheme als Fallbackwert verwendet.
oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
Bereiche für openid und profile (Scope) (Optional): Die Bereiche openid und profile werden ebenfalls standardmäßig konfiguriert, da Sie erforderlich sind, damit der OIDC-Handler funktioniert. Sie müssen jedoch möglicherweise erneut hinzugefügt werden, wenn Bereiche in der Authentication:Schemes:MicrosoftOidc:Scope-Konfiguration enthalten sind. Allgemeine Anleitungen zur Konfiguration finden Sie unter Konfiguration in ASP.NET Core und ASP.NET Core-Blazor-Konfiguration.
oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
SaveTokens: Definiert, ob Zugriffs- und Aktualisierungstoken nach einer erfolgreichen Autorisierung in AuthenticationProperties gespeichert werden sollen. Diese Eigenschaft ist auf true festgelegt, sodass das Aktualisierungstoken für eine nicht interaktive Tokenaktualisierung gespeichert wird.
oidcOptions.SaveTokens = true;
Bereich für den Offlinezugriff (Scope): Der Bereich offline_access ist für das Aktualisierungstoken erforderlich.
oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
Authority und ClientId: Legt die Autoritäts- und Client-ID für OIDC-Aufrufe fest.
oidcOptions.Authority = "{AUTHORITY}";
oidcOptions.ClientId = "{CLIENT ID}";
Im folgenden Beispiel wird eine Mandanten-ID von aaaabbbb-0000-cccc-1111-dddd2222eeee und eine Client-ID von 00001111-aaaa-2222-bbbb-3333cccc4444 verwendet:
oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
Bei Mehrinstanzen-Apps sollte die "gemeinsame" Autorität verwendet werden. Sie können die Autorität „common“ auch für einzelinstanzenfähige Apps verwenden, allerdings ist ein benutzerdefinierter IssuerValidator-Wert erforderlich, wie weiter unten in diesem Abschnitt gezeigt.
oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0";
ResponseType: Konfiguriert den OIDC-Handler so, dass nur der Autorisierungscodeflow ausgeführt wird. Implizite Genehmigungen und Hybridflows sind in diesem Modus nicht erforderlich. Der OIDC-Handler fordert automatisch die entsprechenden Token mithilfe des vom Autorisierungsendpunkt zurückgegebenen Codes an.
oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
MapInboundClaims und die Konfiguration von NameClaimType und RoleClaimType: Viele OIDC-Server verwenden name und role anstelle der Standardwerte für SOAP/WS-Fed in ClaimTypes. Wenn MapInboundClaims auf false festgelegt ist, führt der Handler keine Anspruchszuordnungen durch und die Anspruchsnamen aus dem JWT werden direkt von der App verwendet. Im folgenden Beispiel wird der Rollenanspruchstyp auf roles festgelegt, was für Microsoft Entra ID (ME-ID) geeignet ist. Weitere Informationen finden Sie in der Dokumentation Ihres Identitätsanbieters.
Note
MapInboundClaims muss für die meisten OIDC-Anbieter auf false festgelegt werden, um das Umbenennen von Ansprüchen zu verhindern.
oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = "name";
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
Pfadkonfiguration: Die Pfade müssen mit den bei der Registrierung der Anwendung beim OIDC-Anbieter konfigurierten Pfaden für den Umleitungs-URI (Login-Rückrufpfad) und für die Umleitung nach der Abmeldung (Abmelde-Rückrufpfad) übereinstimmen. Im Azure-Portal werden Pfade auf dem Blatt Authentifizierung der App-Registrierung konfiguriert. Sowohl die Anmelde- als auch die Abmeldepfade müssen als Umleitungs-URIs registriert werden. Die Standardwerte sind /signin-oidc und /signout-callback-oidc.
CallbackPath: Der Anforderungspfad im Basispfad der Anwendung, an den der Benutzer-Agent zurückgegeben wird
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signin-oidc
Note
Bei Verwendung von Microsoft Entra ID ist für localhost kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
SignedOutCallbackPath (Konfigurationsschlüssel: "SignedOutCallbackPath"): Der Anforderungspfad innerhalb des Basispfads der App, der vom OIDC-Handler abgefangen wird, wo der Benutzer-Agent nach der Abmeldung vom Identitätsanbieter zuerst zurückgeleitet wird. Die Beispiel App legt keinen Wert für den Pfad fest, da der Standardwert "/signout-callback-oidc" verwendet wird. Nach dem Abfangen der Anfrage leitet der OIDC Handler auf die SignedOutRedirectUri oder RedirectUri um, falls angegeben.
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signout-callback-oidc
Note
Legen Sie bei Verwendung der Microsoft Entra-ID den Pfad in den Redirect URI-Konfigurationseinträgen der Web-Plattform im Entra- oder Azure-Portal fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port. Wenn Sie den Rückrufpfad-URI für abgemeldete Benutzer nicht zur Registrierung der App bei Entra hinzufügen, lehnt Entra die Weiterleitung des Benutzers an die App ab und fordert ihn lediglich auf, das Browserfenster zu schließen.
RemoteSignOutPath: Anforderungen, die unter diesem Pfad empfangen werden, veranlassen den Handler, die Abmeldung mithilfe des Abmeldeschemas auszulösen.
Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost/signout-oidc
Note
Wenn Sie Microsoft Entra ID verwenden, legen Sie im Entra- oder Azure-Portal die Front-Channel Logout URL fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
oidcOptions.CallbackPath = new PathString("{PATH}");
oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
Beispiele (Standardwerte):
oidcOptions.CallbackPath = new PathString("/signin-oidc");
oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
(Microsoft Azure nur mit dem Endpunkt „common“) TokenValidationParameters.IssuerValidator: Viele OIDC-Anbieter arbeiten mit dem Standardaussteller-Validierer. Wir müssen jedoch den Aussteller berücksichtigen, der mit der von {TENANT ID} zurückgegebenen Mandanten-ID (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) parametrisiert ist. Weitere Informationen finden Sie unter SecurityTokenInvalidIssuerException bei OpenID Connect und beim Azure AD-Endpunkt „common“ (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).
Nur für Apps, die Microsoft Entra ID oder Azure AD B2C mit dem Endpunkt „common“ verwenden:
var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
Blazor Web App Kundenprojekt (BlazorWebAppOidc.Client)
Das BlazorWebAppOidc.Client-Projekt ist das clientseitige Projekt des Blazor Web App.
Der Client ruft AddAuthenticationStateDeserialization auf, um den vom Server übergebenen Authentifizierungsstatus zu deserialisieren und zu verwenden. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
Die Klasse PersistentAuthenticationStateProvider (PersistentAuthenticationStateProvider.cs) ist ein clientseitiges AuthenticationStateProvider-Element, das den Authentifizierungsstatus der Benutzer bzw. Benutzerinnen bestimmt, indem nach Daten gesucht wird, die auf der Seite gespeicherten wurden, als diese auf dem Server gerendert wurde. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
Wenn sich Benutzer bzw. Benutzerinnen an- oder abmelden muss, muss die Seite vollständig neu geladen werden.
Die Beispiel-App stellt nur einen Benutzernamen und eine E-Mail für die Anzeige bereit.
Für Microsoft Entra ID oder Azure AD B2C können Sie AddMicrosoftIdentityWebApp von Microsoft Identity Web (Microsoft.Identity.Web, API-Dokumentation) verwenden, das sowohl die OIDC- als auch die Authentifizierungs-Handler mit den entsprechenden Standardwerten hinzufügt. Die Beispiel-App und die Anleitungen in diesem Artikel verwenden Microsoft Identity Web nicht. Die Anleitung veranschaulicht, wie der OIDC-Handler manuell für die einzelnen OIDC-Anbieter konfiguriert wird. Weitere Informationen zur Implementierung von Microsoft Identity Web finden Sie unter Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID.
Diese Version des Artikels behandelt die Implementierung von OIDC ohne Adaption des Backend for Frontend (BFF)-Musters mit einer App, die das globale interaktive Server-Rendering (einzelnes Projekt) einsetzt. Das BFF-Muster ist nützlich, um authentifizierte Anforderungen an externe Dienste zu senden. Ändern Sie den Selektor für die Artikelversion in BFF-Muster , wenn die Spezifikation der Anwendung die Übernahme des BFF-Musters mit globalem Interactive Auto Rendering vorsieht.
Die folgende Spezifikation wird angenommen:
- Das Blazor Web App verwendet den Server-Rendering-Modus mit globaler Interaktivität.
- Diese App ist ein Ausgangspunkt für jeden OIDC-Authentifizierungsflow. OIDC wird manuell in der App konfiguriert und ist nicht auf Microsoft Entra ID oder Microsoft Identity Web-Pakete angewiesen, und die Beispiel-App erfordert kein Microsoft Azure-Hosting. Die Beispiel-App kann jedoch mit Entra und Microsoft Identity Web verwendet und in Azure gehostet werden.
- Automatische nicht interaktive Tokenaktualisierung
- Ein separates Web-API-Projekt veranschaulicht einen sicheren Web-API-Aufruf für Wetterdaten.
Eine alternative Erfahrung mit Microsoft Authentication Library for .NET, Microsoft Identity Web und Microsoft Entra ID finden Sie unter Sichern eines ASP.NET Core Blazor Web App mit Microsoft Entra ID.
Beispiellösung
Die Beispiel-App besteht aus den folgenden Projekten:
-
BlazorWebAppOidcServer: Blazor Web App serverseitiges Projekt (globales interaktives Serverrendering). -
MinimalApiJwt: Back-End-Web-API mit einem minimalen API-Endpunkt für Wetterdaten.
Greifen Sie auf das Beispiel über den neuesten Versionsordner im Repository für Blazor Beispiele mit dem folgenden Link zu. Das Beispiel befindet sich im Ordner BlazorWebAppOidcServer für .NET 8 oder höher.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Microsoft Entra ID-App-Registrierungen
Es wird empfohlen, separate Registrierungen für Apps und Web-APIs zu verwenden, auch wenn sich die Apps und Web-APIs in derselben Lösung befinden. Der folgende Leitfaden richtet sich an die BlazorWebAppOidcServer App- und MinimalApiJwt Web-API der Beispiellösung, gilt jedoch im Allgemeinen für alle Entra-basierten Registrierungen für Apps und Web-APIs.
Registrieren Sie zuerst die Web-API (MinimalApiJwt), damit Sie beim Registrieren der App Zugriff auf die Web-API gewähren können. Die Mandanten-ID und Client-ID der Web-API werden verwendet, um die Web-API in ihrer Program Datei zu konfigurieren. Nachdem Sie die Web-API registriert haben, exponieren Sie die Web-API in App-Registrierungen>API exponieren mit einem Bereichsnamen von Weather.Get. Notieren Sie den App-ID-URI für die Verwendung in der App-Konfiguration.
Registrieren Sie als Nächstes die App (BlazorWebAppOidcServer) mit einer Webplattformkonfiguration und einem Umleitungs-URI von https://localhost/signin-oidc (ein Port ist nicht erforderlich). Die Mandanten-ID und die Client-ID der App werden zusammen mit Basisadresse der Web-API, App-ID-URI und Wetterbereichsnamen verwendet, um die App in ihrer Program-Datei zu konfigurieren. Erteilen Sie API-Berechtigungen zum Zugriff auf die Web-API unter App-Registrierungen>API-Berechtigungen. Wenn die Sicherheitsspezifikation der App dies aufruft, können Sie der Organisation die Zustimmung des Administrators für den Zugriff auf die Web-API erteilen. Autorisierte Benutzer und Gruppen werden der Registrierung der App in App-Registrierungen>Enterprise-Anwendungen zugewiesen.
Konfigurieren Sie in der Entra- oder Azure-Portal-Konfiguration der impliziten Genehmigung und hybriden Bewegungsarten der App-Registrierung, dass Sie kein Kontrollkästchen aktivieren, damit der Autorisierungsendpunkt keine Zugriffstoken oder ID-Token zurückgibt. Der OpenID Connect-Anforderungshandler fordert automatisch die entsprechenden Token an, indem er den vom Autorisierungsendpunkt zurückgegebenen Code verwendet.
Erstellen Sie ein Client-Geheimnis in der App-Registrierung im Entra- oder Azure-Portal (Verwalten>Zertifikate und Geheimnisse>neues Client-Geheimnis). Warten Sie auf den geheimen Clientschlüssel Wert zur Nutzung im nächsten Abschnitt.
Weitere Anleitungen zur Entra-Konfiguration für bestimmte Einstellungen finden Sie weiter unten in diesem Artikel.
Einrichten des geheimen Clientschlüssels
Dieser Abschnitt gilt nur für das Serverprojekt des Blazor Web App (BlazorWebAppOidcServer Projekts).
Warning
Speichern Sie keine geheimen App-Schlüssel, Verbindungszeichenfolge s, Anmeldeinformationen, Kennwörter, persönliche Identifikationsnummern (PINs), privaten C#/.NET-Code oder private Schlüssel/Token im clientseitigen Code, der immer unsicher ist. In Test-/Staging- und Produktionsumgebungen sollten serverseitiger Blazor Code und Web-APIs sichere Authentifizierungsflüsse verwenden, die vermeiden, Anmeldedaten im Projektcode oder in Konfigurationsdateien zu speichern. Außerhalb der lokalen Entwicklungstests wird empfohlen, die Verwendung von Umgebungsvariablen zum Speichern vertraulicher Daten zu vermeiden, da Umgebungsvariablen nicht der sicherste Ansatz sind. Für lokale Entwicklungstests wird das Tool "Geheimer Manager" zum Sichern vertraulicher Daten empfohlen. Weitere Informationen finden Sie unter "Sichere Verwaltung vertraulicher Daten und Anmeldeinformationen".
Verwenden Sie für lokale Entwicklungstests das Tool "Geheimer Manager ", um den geheimen Clientschlüssel des Blazor Serverprojekts unter dem Konfigurationsschlüssel Authentication:Schemes:MicrosoftOidc:ClientSecretzu speichern.
Das Blazor Serverprojekt wurde für das Tool "Geheimer Manager" nicht initialisiert. Verwenden Sie eine Befehlsshell, z. B. die PowerShell-Befehlsshell für Entwickler in Visual Studio, um den folgenden Befehl auszuführen. Ändern Sie vor dem Ausführen des Befehls das Verzeichnis mit dem cd Befehl in das Verzeichnis des Serverprojekts. Der Befehl richtet einen Bezeichner für geheime Benutzerschlüssel ein (<UserSecretsId> in der Projektdatei der App):
dotnet user-secrets init
Führen Sie den folgenden Befehl aus, um den geheimen Clientschlüssel festzulegen. Der {SECRET} Platzhalter ist der geheime Clientschlüssel, der aus der Registrierung der App abgerufen wird:
dotnet user-secrets set "Authentication:Schemes:MicrosoftOidc:ClientSecret" "{SECRET}"
Wenn Sie Visual Studio verwenden, können Sie bestätigen, dass der geheime Schlüssel festgelegt ist, indem Sie mit der rechten Maustaste auf das Projekt im Projektmappen-Explorer klicken und Benutzergeheimnisse verwalten auswählen.
MinimalApiJwt Projekt
Das Projekt MinimalApiJwt ist eine Back-End-Web-API für mehrere Front-End-Projekte. Das Projekt konfiguriert einen Endpunkt für die Minimal-API für Wetterdaten.
Die Datei MinimalApiJwt.http kann zum Testen der Wetterdatenanforderung verwendet werden. Beachten Sie, dass das MinimalApiJwt-Projekt ausgeführt werden muss, um den Endpunkt zu testen, wobei der Endpunkt in der Datei hartcodiert ist. Weitere Informationen finden Sie unter Verwenden von HTTP-Dateien in Visual Studio 2022.
Das Projekt enthält Pakete und Konfigurationen zum Erstellen von OpenAPI-Dokumenten.
Das Projekt enthält Pakete und Konfigurationen, um OpenAPI-Dokumente und die Swagger-UI in der Entwicklungsumgebung zu erstellen. Weitere Informationen finden Sie unter Verwenden der generierten OpenAPI-Dokumente.
Das Projekt erstellt einen minimalen API-Endpunkt für Wetterdaten:
app.MapGet("/weather-forecast", () =>
{
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;
}).RequireAuthorization();
Konfigurieren Sie das Projekt in den JwtBearerOptions des AddJwtBearer-Aufrufs in der Datei Program des Projekts.
Authority legt die Autorität für das Tätigen von OIDC-Aufrufen fest. Es wird empfohlen, eine separate App-Registrierung für das MinimalApiJwt Projekt zu verwenden. Die Autorität entspricht dem Aussteller (iss) des vom Identitätsanbieter zurückgegebenen JWT.
jwtOptions.Authority = "{AUTHORITY}";
Das Format der Autorität hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden die Mandanten-ID aaaabbbb-0000-cccc-1111-dddd2222eeee.
Beispiel für ME-ID-Mandantenautorität:
jwtOptions.Authority = "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee";
Beispiel für AAD B2C-Mandantenautorität:
jwtOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
Audience legt die Zielgruppe für empfangene OIDC-Token fest.
jwtOptions.Audience = "{APP ID URI}";
Note
Wenn Sie Microsoft Entra ID verwenden, stimmen Sie den Wert mit dem Pfad der Anwendungs-ID URI ab, die beim Hinzufügen des Weather.Get -Bereichs unter Expose an API im Entra- oder Azure-Portal konfiguriert wurde. Fügen Sie den Bereichsnamen "Weather.Get," nicht in den Wert ein.
Das Format der Zielgruppe hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden eine Mandanten-ID von contoso und eine Client-ID von 11112222-bbbb-3333-cccc-4444dddd5555.
Beispiel für die App-ID-URI des ME-ID-Mandanten:
jwtOptions.Audience = "api://11112222-bbbb-3333-cccc-4444dddd5555";
Beispiel für die App-ID-URI des AAD B2C-Mandanten:
jwtOptions.Audience = "https://contoso.onmicrosoft.com/11112222-bbbb-3333-cccc-4444dddd5555";
BlazorWebAppOidcServer Projekt
Die automatische Aktualisierung von nicht-interaktiven Tokens wird von einer benutzerdefinierten cookie-Aktualisierungsfunktion (CookieOidcRefresher.cs) verarbeitet.
Ein DelegatingHandler (TokenHandler) verwaltet das Anfügen des Benutzerzugriffstokens an ausgehende Anforderungen. Der Tokenhandler wird nur während des statischen serverseitigen Renderings (statischer SSR) ausgeführt. Daher ist die Verwendung HttpContext in diesem Szenario sicher. Weitere Informationen finden Sie unter "IHttpContextAccessor/HttpContext" in ASP.NET Core-Apps Blazor und ASP.NET Core serverseitige und Blazor Web App zusätzliche Sicherheitsszenarien.
TokenHandler.cs:
public class TokenHandler(IHttpContextAccessor httpContextAccessor) :
DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (httpContextAccessor.HttpContext is null)
{
throw new Exception("HttpContext not available");
}
var accessToken = await httpContextAccessor.HttpContext
.GetTokenAsync("access_token");
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
return await base.SendAsync(request, cancellationToken);
}
}
In der Datei des Program-Projekts wird der Tokenhandler (TokenHandler) als Dienst registriert und als Nachrichtenhandler festgelegt, um mit AddHttpMessageHandler sichere Anforderungen an die Back-End-MinimalApiJwt-Web-API mithilfe eines benannten HTTP-Clients ("ExternalApi") zu stellen.
builder.Services.AddScoped<TokenHandler>();
builder.Services.AddHttpClient("ExternalApi",
client => client.BaseAddress = new Uri(builder.Configuration["ExternalApiUri"] ??
throw new Exception("Missing base address!")))
.AddHttpMessageHandler<TokenHandler>();
Die Weather Komponente verwendet das [Authorize]-Attribut, um unbefugten Zugriff zu verhindern. Weitere Informationen dazu, wie Sie die Autorisierung in der gesamten App über eine Autorisierungsrichtlinie verlangen und die Autorisierung an einer Untermenge von öffentlichen Endpunkten ausschließen können, finden Sie in der RazorSeiten OIDC Anleitung.
Der ExternalApi HTTP-Client wird verwendet, um eine Anforderung für Wetterdaten an die sichere Web-API zu senden. Im Lebenszyklusereignis OnInitializedAsync von Weather.razor:
using var request = new HttpRequestMessage(HttpMethod.Get, "/weather-forecast");
var client = ClientFactory.CreateClient("ExternalApi");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
forecasts = await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
Konfigurieren Sie den URI der externen API in der appsettings.json-Datei des Projekts:
"ExternalApiUri": "{BASE ADDRESS}"
Example:
"ExternalApiUri": "https://localhost:7277"
Die folgende OpenIdConnectOptions-Konfiguration befindet sich in der Datei Program des Projekts beim Aufruf von AddOpenIdConnect:
PushedAuthorizationBehavior: Steuert den Pushed Authorization Requests (PAR)-Support. Standardmäßig ist die Einstellung so, dass PAR verwendet wird, wenn das Discovery-Dokument des Identitätsanbieters (normalerweise unter .well-known/openid-configuration) den Support für PAR ankündigt. Wenn Sie den PAR-Support für die App erwerben möchten, weisen Sie einen Wert von PushedAuthorizationBehavior.Require zu. PAR wird nicht von Microsoft Entra unterstützt und es gibt auch keine Pläne diesbezüglich für die Zukunft.
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.UseIfAvailable;
SignInScheme: Legt das Authentifizierungsschema fest, das der Middleware entspricht, die für die Beibehaltung der Identität von Benutzern bzw. Benutzerinnen nach einer erfolgreichen Authentifizierung verantwortlich ist. Der OIDC-Handler muss ein Anmeldeschema verwenden, das Benutzeranmeldeinformationen über Anforderungen hinweg beibehalten kann. Die folgende Zeile dient ist lediglich der Veranschaulichung. Wird sie weggelassen, wird DefaultSignInScheme als Fallbackwert verwendet.
oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
Bereiche für openid und profile (Scope) (Optional): Die Bereiche openid und profile werden ebenfalls standardmäßig konfiguriert, da Sie erforderlich sind, damit der OIDC-Handler funktioniert. Sie müssen jedoch möglicherweise erneut hinzugefügt werden, wenn Bereiche in der Authentication:Schemes:MicrosoftOidc:Scope-Konfiguration enthalten sind. Allgemeine Anleitungen zur Konfiguration finden Sie unter Konfiguration in ASP.NET Core und ASP.NET Core-Blazor-Konfiguration.
oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
Konfigurieren Sie den Weather.Get-Bereich zum Zugriff auf die externe Web-API für Wetterdaten. Das folgende Beispiel basiert auf der Verwendung der Entra-ID in einer ME-ID Mandantendomäne. Im folgenden Beispiel wird der {APP ID URI} Platzhalter im Entra- oder Azure-Portal gefunden, in dem die Web-API verfügbar gemacht wird. Verwenden Sie für jeden anderen Identitätsanbieter den relevanten Reservierungsumfang.
oidcOptions.Scope.Add("{APP ID URI}/Weather.Get");
Das Format für den Reservierungsumfang hängt vom verwendeten Mandantentyp ab. In den folgenden Beispielen lautet contoso.onmicrosoft.comdie Mandantendomäne , und die Client-ID lautet 11112222-bbbb-3333-cccc-4444dddd5555.
Beispiel für die App-ID-URI des ME-ID-Mandanten:
oidcOptions.Scope.Add("api://11112222-bbbb-3333-cccc-4444dddd5555/Weather.Get");
Beispiel für die App-ID-URI des AAD B2C-Mandanten:
oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/11112222-bbbb-3333-cccc-4444dddd5555/Weather.Get");
SaveTokens: Definiert, ob Zugriffs- und Aktualisierungstoken nach einer erfolgreichen Autorisierung in AuthenticationProperties gespeichert werden sollen. Diese Eigenschaft ist auf true festgelegt, sodass das Aktualisierungstoken für eine nicht interaktive Tokenaktualisierung gespeichert wird.
oidcOptions.SaveTokens = true;
Bereich für den Offlinezugriff (Scope): Der Bereich offline_access ist für das Aktualisierungstoken erforderlich.
oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
Authority und ClientId: Legt die Autoritäts- und Client-ID für OIDC-Aufrufe fest.
oidcOptions.Authority = "{AUTHORITY}";
oidcOptions.ClientId = "{CLIENT ID}";
Im folgenden Beispiel wird eine Mandanten-ID von aaaabbbb-0000-cccc-1111-dddd2222eeee und eine Client-ID von 00001111-aaaa-2222-bbbb-3333cccc4444 verwendet:
oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
Bei Mehrinstanzen-Apps sollte die "gemeinsame" Autorität verwendet werden. Sie können die Autorität „common“ auch für einzelinstanzenfähige Apps verwenden, allerdings ist ein benutzerdefinierter IssuerValidator-Wert erforderlich, wie weiter unten in diesem Abschnitt gezeigt.
oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0";
ResponseType: Konfiguriert den OIDC-Handler so, dass nur der Autorisierungscodeflow ausgeführt wird. Implizite Genehmigungen und Hybridflows sind in diesem Modus nicht erforderlich. Der OIDC-Handler fordert automatisch die entsprechenden Token mithilfe des vom Autorisierungsendpunkt zurückgegebenen Codes an.
oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
MapInboundClaims und die Konfiguration von NameClaimType und RoleClaimType: Viele OIDC-Server verwenden name und role anstelle der Standardwerte für SOAP/WS-Fed in ClaimTypes. Wenn MapInboundClaims auf false festgelegt ist, führt der Handler keine Anspruchszuordnungen durch und die Anspruchsnamen aus dem JWT werden direkt von der App verwendet. Im folgenden Beispiel wird der Rollenanspruchstyp auf roles festgelegt, was für Microsoft Entra ID (ME-ID) geeignet ist. Weitere Informationen finden Sie in der Dokumentation Ihres Identitätsanbieters.
Note
MapInboundClaims muss für die meisten OIDC-Anbieter auf false festgelegt werden, um das Umbenennen von Ansprüchen zu verhindern.
oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = "name";
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
Pfadkonfiguration: Die Pfade müssen mit den bei der Registrierung der Anwendung beim OIDC-Anbieter konfigurierten Pfaden für den Umleitungs-URI (Login-Rückrufpfad) und für die Umleitung nach der Abmeldung (Abmelde-Rückrufpfad) übereinstimmen. Im Azure-Portal werden Pfade auf dem Blatt Authentifizierung der App-Registrierung konfiguriert. Sowohl die Anmelde- als auch die Abmeldepfade müssen als Umleitungs-URIs registriert werden. Die Standardwerte sind /signin-oidc und /signout-callback-oidc.
CallbackPath: Der Anforderungspfad im Basispfad der Anwendung, an den der Benutzer-Agent zurückgegeben wird
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signin-oidc
Note
Bei Verwendung von Microsoft Entra ID ist für localhost kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
SignedOutCallbackPath (Konfigurationsschlüssel: "SignedOutCallbackPath"): Der Anforderungspfad innerhalb des Basispfads der App, der vom OIDC-Handler abgefangen wird, wo der Benutzer-Agent nach der Abmeldung vom Identitätsanbieter zuerst zurückgeleitet wird. Die Beispiel App legt keinen Wert für den Pfad fest, da der Standardwert "/signout-callback-oidc" verwendet wird. Nach dem Abfangen der Anfrage leitet der OIDC Handler auf die SignedOutRedirectUri oder RedirectUri um, falls angegeben.
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signout-callback-oidc
Note
Legen Sie bei Verwendung der Microsoft Entra-ID den Pfad in den Redirect URI-Konfigurationseinträgen der Web-Plattform im Entra- oder Azure-Portal fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port. Wenn Sie den Rückrufpfad-URI für abgemeldete Benutzer nicht zur Registrierung der App bei Entra hinzufügen, lehnt Entra die Weiterleitung des Benutzers an die App ab und fordert ihn lediglich auf, das Browserfenster zu schließen.
RemoteSignOutPath: Anforderungen, die unter diesem Pfad empfangen werden, veranlassen den Handler, die Abmeldung mithilfe des Abmeldeschemas auszulösen.
Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost/signout-oidc
Note
Wenn Sie Microsoft Entra ID verwenden, legen Sie im Entra- oder Azure-Portal die Front-Channel Logout URL fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
oidcOptions.CallbackPath = new PathString("{PATH}");
oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
Beispiele (Standardwerte):
oidcOptions.CallbackPath = new PathString("/signin-oidc");
oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
(Microsoft Azure nur mit dem Endpunkt „common“) TokenValidationParameters.IssuerValidator: Viele OIDC-Anbieter arbeiten mit dem Standardaussteller-Validierer. Wir müssen jedoch den Aussteller berücksichtigen, der mit der von {TENANT ID} zurückgegebenen Mandanten-ID (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) parametrisiert ist. Weitere Informationen finden Sie unter SecurityTokenInvalidIssuerException bei OpenID Connect und beim Azure AD-Endpunkt „common“ (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).
Nur für Apps, die Microsoft Entra ID oder Azure AD B2C mit dem Endpunkt „common“ verwenden:
var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
Für Microsoft Entra ID oder Azure AD B2C können Sie AddMicrosoftIdentityWebApp von Microsoft Identity Web (Microsoft.Identity.Web, API-Dokumentation) verwenden, das sowohl die OIDC- als auch die Authentifizierungs-Handler mit den entsprechenden Standardwerten hinzufügt. Die Beispiel-App und die Anleitungen in diesem Artikel verwenden Microsoft Identity Web nicht. Die Anleitung veranschaulicht, wie der OIDC-Handler manuell für die einzelnen OIDC-Anbieter konfiguriert wird. Weitere Informationen zur Implementierung von Microsoft Identity Web finden Sie unter Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID.
Diese Version des Artikels behandelt die Implementierung von OIDC mit dem BFF-Muster (Back-End für Front-Ends). Wenn die Spezifikation der App nicht zum Übernehmen des BFF-Musters aufruft, ändern Sie die Artikelversionsauswahl in Nicht-BFF-Muster (Interaktives Autorendering) oder Nicht-BFF-Muster (Interaktives Serverrendering).
Prerequisites
Aspire erfordert Visual Studio Version 17.10 oder höher.
Weitere Informationen finden Sie im Abschnitt "Voraussetzungen" der Schnellstartanleitung: Erstellen Ihrer ersten Aspire Lösung.
Beispiellösung
Die Beispiel-App besteht aus den folgenden Projekten:
-
Aspire:
-
Aspire.AppHost: Wird verwendet, um die übergeordneten Orchestrierungsaufgaben der App zu verwalten. -
Aspire.ServiceDefaults: Enthält Standardkonfigurationen für Aspire Apps, die nach Bedarf erweitert und angepasst werden können.
-
-
MinimalApiJwt: Back-End-Web-API mit einem Beispielendpunkt für die Minimal-API für Wetterdaten. -
BlazorWebAppOidc: Server-seitiges Projekt der Blazor Web App. Das Projekt nutzt YARP, um Anforderungen per Proxy an einen Wettervorhersageendpunkt im Back-End-Web-API-Projekt weiterzuleiten, wobei dasMinimalApiJwtim Authentifizierungsaccess_tokengespeichert wird. -
BlazorWebAppOidc.Client: Clientseitiges Projekt der Blazor Web App.
Greifen Sie auf das Beispiel über den neuesten Versionsordner im Repository für Blazor Beispiele mit dem folgenden Link zu. Das Beispiel befindet sich im Ordner BlazorWebAppOidcBff für .NET 8 oder höher.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Die Blazor Web App verwendet den automatischen Rendermodus mit globaler Interaktivität.
Das Serverprojekt ruft AddAuthenticationStateSerialization auf, um einen serverseitigen Authentifizierungsstatusanbieter hinzuzufügen, der PersistentComponentState verwendet, um den Authentifizierungsstatus zum Client zu übertragen. Der Client ruft AddAuthenticationStateDeserialization auf, um den vom Server übergebenen Authentifizierungsstatus zu deserialisieren und zu verwenden. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
Die Klasse PersistingAuthenticationStateProvider (PersistingAuthenticationStateProvider.cs) ist ein serverseitiges AuthenticationStateProvider-Element, das PersistentComponentState verwendet, um den Authentifizierungsstatus an den Client zu senden, der dann für die Lebensdauer der WebAssembly-Anwendung festgelegt wird.
Diese App ist ein Ausgangspunkt für jeden OIDC-Authentifizierungsflow. OIDC wird manuell in der App konfiguriert und ist nicht auf Microsoft Entra ID oder Microsoft Identity Web-Pakete angewiesen, und die Beispiel-App erfordert kein Microsoft Azure-Hosting. Die Beispiel-App kann jedoch mit Entra und Microsoft Identity Web verwendet und in Azure gehostet werden.
Automatische, nicht interaktive Tokenaktualisierung mithilfe eines benutzerdefinierten cookie-Aktualisierers (CookieOidcRefresher.cs).
Das Backend for Frontend (BFF) Muster wird mit Aspire für die Service-Erkennung und YARP für die Weiterleitung von Anfragen an einen Wettervorhersage-Endpunkt in der Backend-App übernommen.
Die Back-End-Web-API (MinimalApiJwt) verwendet die JWT-Bearer-Authentifizierung, um JWT-Token zu validieren, die von Blazor Web App im Anmelde-cookie gespeichert wurden.
Aspire verbessert die Erfahrung beim Erstellen von .NET Cloud-nativen Apps. Es bietet einen konsistenten, festgelegten Satz von Tools und Mustern zum Entwickeln und Betreiben verteilter Apps.
YARP (Yet Another Reverse Proxy) ist eine Bibliothek, die zum Erstellen eines Reverseproxyservers verwendet wird.
MapForwarder in der Program Datei des Serverprojekts fügt die direkte Weiterleitung von HTTP-Anforderungen hinzu, die mit dem angegebenen Muster mit einem bestimmten Ziel übereinstimmen, indem die Standardkonfiguration für die ausgehende Anforderung, angepasste Transformationen und der Standard-HTTP-Client verwendet wird:
- Beim Rendern der
Weather-Komponente auf dem Server verwendet die Komponente dieServerWeatherForecaster-Klasse, um die Anforderung für Wetterdaten mit dem Zugriffstoken des Benutzers weiterzuleiten. IHttpContextAccessor.HttpContext bestimmt, ob eine HttpContext für die Verwendung durch dieGetWeatherForecastAsync-Methode verfügbar ist. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core. - Wenn die Komponente auf dem Client gerendert wird, verwendet die Komponente die
ClientWeatherForecasterDienstimplementierung, die eine vorkonfigurierte HttpClient (in der Datei des ClientprojektsProgram) verwendet, um einen Web-API-Aufruf an das Serverprojekt durchzuführen. Ein minimaler API-Endpunkt (/weather-forecast), der in der Datei des ServerprojektsProgramdefiniert ist, transformiert die Anforderung mit dem Zugriffstoken des Benutzers, um die Wetterdaten abzurufen.
Weitere Informationen zu (Web-)API-Aufrufen unter Verwendung von Dienstabstraktionen in Blazor Web Apps finden Sie unter Aufruf einer Web-API von einer ASP.NET Core-Blazor-App.
Microsoft Entra ID-App-Registrierungen
Es wird empfohlen, separate Registrierungen für Apps und Web-APIs zu verwenden, auch wenn sich die Apps und Web-APIs in derselben Lösung befinden. Der folgende Leitfaden richtet sich an die BlazorWebAppOidc App- und MinimalApiJwt Web-API der Beispiellösung, gilt jedoch im Allgemeinen für alle Entra-basierten Registrierungen für Apps und Web-APIs.
Registrieren Sie zuerst die Web-API (MinimalApiJwt), damit Sie beim Registrieren der App Zugriff auf die Web-API gewähren können. Die Mandanten-ID und Client-ID der Web-API werden verwendet, um die Web-API in ihrer Program Datei zu konfigurieren. Nachdem Sie die Web-API registriert haben, exponieren Sie die Web-API in App-Registrierungen>API exponieren mit einem Bereichsnamen von Weather.Get. Notieren Sie den App-ID-URI für die Verwendung in der App-Konfiguration.
Registrieren Sie als Nächstes die App (BlazorWebAppOidc/BlazorWebApOidc.Client) mit einer Webplattformkonfiguration und einem Umleitungs-URI von https://localhost/signin-oidc (ein Port ist nicht erforderlich). Die Mandanten-ID und die Client-ID der App werden zusammen mit Basisadresse der Web-API, App-ID-URI und Wetterbereichsnamen verwendet, um die App in ihrer Program-Datei zu konfigurieren. Erteilen Sie API-Berechtigungen zum Zugriff auf die Web-API unter App-Registrierungen>API-Berechtigungen. Wenn die Sicherheitsspezifikation der App dies aufruft, können Sie der Organisation die Zustimmung des Administrators für den Zugriff auf die Web-API erteilen. Autorisierte Benutzer und Gruppen werden der Registrierung der App in App-Registrierungen>Enterprise-Anwendungen zugewiesen.
Konfigurieren Sie in der Entra- oder Azure-Portal-Konfiguration der impliziten Genehmigung und hybriden Bewegungsarten der App-Registrierung, dass Sie kein Kontrollkästchen aktivieren, damit der Autorisierungsendpunkt keine Zugriffstoken oder ID-Token zurückgibt. Der OpenID Connect-Anforderungshandler fordert automatisch die entsprechenden Token an, indem er den vom Autorisierungsendpunkt zurückgegebenen Code verwendet.
Erstellen Sie ein Client-Geheimnis in der App-Registrierung im Entra- oder Azure-Portal (Verwalten>Zertifikate und Geheimnisse>neues Client-Geheimnis). Warten Sie auf den geheimen Clientschlüssel Wert zur Nutzung im nächsten Abschnitt.
Weitere Anleitungen zur Entra-Konfiguration für bestimmte Einstellungen finden Sie weiter unten in diesem Artikel.
Einrichten des geheimen Clientschlüssels
Dieser Abschnitt gilt nur für das Serverprojekt des Blazor Web App (BlazorWebAppOidc Projekts).
Warning
Speichern Sie keine geheimen App-Schlüssel, Verbindungszeichenfolge s, Anmeldeinformationen, Kennwörter, persönliche Identifikationsnummern (PINs), privaten C#/.NET-Code oder private Schlüssel/Token im clientseitigen Code, der immer unsicher ist. In Test-/Staging- und Produktionsumgebungen sollten serverseitiger Blazor Code und Web-APIs sichere Authentifizierungsflüsse verwenden, die vermeiden, Anmeldedaten im Projektcode oder in Konfigurationsdateien zu speichern. Außerhalb der lokalen Entwicklungstests wird empfohlen, die Verwendung von Umgebungsvariablen zum Speichern vertraulicher Daten zu vermeiden, da Umgebungsvariablen nicht der sicherste Ansatz sind. Für lokale Entwicklungstests wird das Tool "Geheimer Manager" zum Sichern vertraulicher Daten empfohlen. Weitere Informationen finden Sie unter "Sichere Verwaltung vertraulicher Daten und Anmeldeinformationen".
Verwenden Sie für lokale Entwicklungstests das Tool "Geheimer Manager ", um den geheimen Clientschlüssel des Blazor Serverprojekts unter dem Konfigurationsschlüssel Authentication:Schemes:MicrosoftOidc:ClientSecretzu speichern.
Das Blazor Serverprojekt wurde für das Tool "Geheimer Manager" nicht initialisiert. Verwenden Sie eine Befehlsshell, z. B. die PowerShell-Befehlsshell für Entwickler in Visual Studio, um den folgenden Befehl auszuführen. Ändern Sie vor dem Ausführen des Befehls das Verzeichnis mit dem cd Befehl in das Verzeichnis des Serverprojekts. Der Befehl richtet einen bezeichner für geheime Benutzerschlüssel ein (<UserSecretsId> in der Projektdatei der Server-App):
dotnet user-secrets init
Führen Sie den folgenden Befehl aus, um den geheimen Clientschlüssel festzulegen. Der {SECRET} Platzhalter ist der geheime Clientschlüssel, der aus der Registrierung der App abgerufen wird:
dotnet user-secrets set "Authentication:Schemes:MicrosoftOidc:ClientSecret" "{SECRET}"
Wenn Sie Visual Studio verwenden, können Sie bestätigen, dass der geheime Schlüssel festgelegt ist, indem Sie in Projektmappen-Explorer mit der rechten Maustaste auf das Serverprojekt klicken und "Benutzergeheimnisse verwalten" auswählen.
Aspire Projekte
Weitere Informationen zur Verwendung von Aspire und Details zu den .AppHost- und .ServiceDefaults-Projekten der Beispiel-App finden Sie in der Aspire-Dokumentation.
Bestätigen Sie, dass Sie die Voraussetzungen für Aspire erfüllt haben. Weitere Informationen finden Sie im Abschnitt "Voraussetzungen" der Schnellstartanleitung: Erstellen Ihrer ersten Aspire Lösung.
Die Beispiel-App konfiguriert nur ein unsicheres HTTP-Startprofil (http) für die Verwendung während der Entwicklungstests. Weitere Informationen, einschließlich eines Beispiels für unsichere und sichere Starteinstellungsprofile, finden Sie unter Zulassen von unsicherem Transport in Aspire (Aspire Dokumentation).
MinimalApiJwt Projekt
Das Projekt MinimalApiJwt ist eine Back-End-Web-API für mehrere Front-End-Projekte. Das Projekt konfiguriert einen Endpunkt für die Minimal-API für Wetterdaten. Anfragen aus dem Blazor Web App server-seitigen Projekt (BlazorWebAppOidc) werden an das MinimalApiJwt-Projekt weitergeleitet.
Die Datei MinimalApiJwt.http kann zum Testen der Wetterdatenanforderung verwendet werden. Beachten Sie, dass das MinimalApiJwt-Projekt ausgeführt werden muss, um den Endpunkt zu testen, wobei der Endpunkt in der Datei hartcodiert ist. Weitere Informationen finden Sie unter Verwenden von HTTP-Dateien in Visual Studio 2022.
Das Projekt enthält Pakete und Konfigurationen zum Erstellen von OpenAPI-Dokumenten.
Das Projekt enthält Pakete und Konfigurationen, um OpenAPI-Dokumente und die Swagger-UI in der Entwicklungsumgebung zu erstellen. Weitere Informationen finden Sie unter Verwenden der generierten OpenAPI-Dokumente.
Ein sicherer Wettervorhersagedatenendpunkt befindet sich in der Datei des Program Projekts:
app.MapGet("/weather-forecast", () =>
{
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;
}).RequireAuthorization();
Für die RequireAuthorization-Erweiterungsmethode ist eine Autorisierung für die Routendefinition erforderlich. Fügen Sie für alle Controller, die Sie dem Projekt hinzufügen, das [Authorize]-Attribut dem Controller oder der Aktion hinzu.
Konfigurieren Sie das Projekt in den JwtBearerOptions des AddJwtBearer-Aufrufs in der Datei Program des Projekts.
Authority legt die Autorität für das Tätigen von OIDC-Aufrufen fest. Es wird empfohlen, eine separate App-Registrierung für das MinimalApiJwt Projekt zu verwenden. Die Autorität entspricht dem Aussteller (iss) des vom Identitätsanbieter zurückgegebenen JWT.
jwtOptions.Authority = "{AUTHORITY}";
Das Format der Autorität hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden die Mandanten-ID aaaabbbb-0000-cccc-1111-dddd2222eeee.
Beispiel für ME-ID-Mandantenautorität:
jwtOptions.Authority = "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee";
Beispiel für AAD B2C-Mandantenautorität:
jwtOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
Audience legt die Zielgruppe für empfangene OIDC-Token fest.
jwtOptions.Audience = "{APP ID URI}";
Note
Wenn Sie Microsoft Entra ID verwenden, stimmen Sie den Wert mit dem Pfad der Anwendungs-ID URI ab, die beim Hinzufügen des Weather.Get -Bereichs unter Expose an API im Entra- oder Azure-Portal konfiguriert wurde. Fügen Sie den Bereichsnamen "Weather.Get," nicht in den Wert ein.
Das Format der Zielgruppe hängt vom verwendeten Mandantentyp ab. Die folgenden Beispiele für Microsoft Entra ID verwenden eine Mandanten-ID von contoso und eine Client-ID von 11112222-bbbb-3333-cccc-4444dddd5555.
Beispiel für die App-ID-URI des ME-ID-Mandanten:
jwtOptions.Audience = "api://11112222-bbbb-3333-cccc-4444dddd5555";
Beispiel für die App-ID-URI des AAD B2C-Mandanten:
jwtOptions.Audience = "https://contoso.onmicrosoft.com/11112222-bbbb-3333-cccc-4444dddd5555";
Server-seitiges Blazor Web App-Projekt (BlazorWebAppOidc)
In diesem Abschnitt wird erläutert, wie Sie das serverseitige Blazor Projekt konfigurieren.
Die folgende OpenIdConnectOptions Konfiguration befindet sich in der Projektdatei Program bei dem Aufruf von AddOpenIdConnect.
PushedAuthorizationBehavior: Steuert den Pushed Authorization Requests (PAR)-Support. Standardmäßig ist die Einstellung so, dass PAR verwendet wird, wenn das Discovery-Dokument des Identitätsanbieters (normalerweise unter .well-known/openid-configuration) den Support für PAR ankündigt. Wenn Sie den PAR-Support für die App erwerben möchten, weisen Sie einen Wert von PushedAuthorizationBehavior.Require zu. PAR wird nicht von Microsoft Entra unterstützt und es gibt auch keine Pläne diesbezüglich für die Zukunft.
oidcOptions.PushedAuthorizationBehavior = PushedAuthorizationBehavior.UseIfAvailable;
SignInScheme: Legt das Authentifizierungsschema fest, das der Middleware entspricht, die für die Beibehaltung der Identität von Benutzern bzw. Benutzerinnen nach einer erfolgreichen Authentifizierung verantwortlich ist. Der OIDC-Handler muss ein Anmeldeschema verwenden, das Benutzeranmeldeinformationen über Anforderungen hinweg beibehalten kann. Die folgende Zeile dient ist lediglich der Veranschaulichung. Wird sie weggelassen, wird DefaultSignInScheme als Fallbackwert verwendet.
oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
Bereiche für openid und profile (Scope) (Optional): Die Bereiche openid und profile werden ebenfalls standardmäßig konfiguriert, da Sie erforderlich sind, damit der OIDC-Handler funktioniert. Sie müssen jedoch möglicherweise erneut hinzugefügt werden, wenn Bereiche in der Authentication:Schemes:MicrosoftOidc:Scope-Konfiguration enthalten sind. Allgemeine Anleitungen zur Konfiguration finden Sie unter Konfiguration in ASP.NET Core und ASP.NET Core-Blazor-Konfiguration.
oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
SaveTokens: Definiert, ob Zugriffs- und Aktualisierungstoken nach einer erfolgreichen Autorisierung in AuthenticationProperties gespeichert werden sollen. Der Wert wird auf true festgelegt, um Anforderungen für Wetterdaten aus dem Back-End-Web-API-Projekt (MinimalApiJwt) zu authentifizieren.
oidcOptions.SaveTokens = true;
Bereich für den Offlinezugriff (Scope): Der Bereich offline_access ist für das Aktualisierungstoken erforderlich.
oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
Bereiche zum Abrufen von Wetterdaten aus der Web-API (Scope): Konfigurieren Sie den Bereich für den Weather.Get Zugriff auf die externe Web-API für Wetterdaten. Im folgenden Beispiel wird der {APP ID URI} Platzhalter im Entra- oder Azure-Portal gefunden, in dem die Web-API verfügbar gemacht wird. Verwenden Sie für jeden anderen Identitätsanbieter den relevanten Reservierungsumfang.
oidcOptions.Scope.Add("{APP ID URI}/Weather.Get");
Das Format für den Reservierungsumfang hängt vom verwendeten Mandantentyp ab. In den folgenden Beispielen lautet contoso.onmicrosoft.comdie Mandantendomäne , und die Client-ID lautet 11112222-bbbb-3333-cccc-4444dddd5555.
Beispiel für die App-ID-URI des ME-ID-Mandanten:
oidcOptions.Scope.Add("api://11112222-bbbb-3333-cccc-4444dddd5555/Weather.Get");
Beispiel für die App-ID-URI des AAD B2C-Mandanten:
oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/11112222-bbbb-3333-cccc-4444dddd5555/Weather.Get");
Authority und ClientId: Legt die Autoritäts- und Client-ID für OIDC-Aufrufe fest.
oidcOptions.Authority = "{AUTHORITY}";
oidcOptions.ClientId = "{CLIENT ID}";
Im folgenden Beispiel wird eine Mandanten-ID von aaaabbbb-0000-cccc-1111-dddd2222eeee und eine Client-ID von 00001111-aaaa-2222-bbbb-3333cccc4444 verwendet:
oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0";
oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
Bei Mehrinstanzen-Apps sollte die "gemeinsame" Autorität verwendet werden. Sie können die Autorität „common“ auch für einzelinstanzenfähige Apps verwenden, allerdings ist ein benutzerdefinierter IssuerValidator-Wert erforderlich, wie weiter unten in diesem Abschnitt gezeigt.
oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0";
ResponseType: Konfiguriert den OIDC-Handler so, dass nur der Autorisierungscodeflow ausgeführt wird. Implizite Genehmigungen und Hybridflows sind in diesem Modus nicht erforderlich. Der OIDC-Handler fordert automatisch die entsprechenden Token mithilfe des vom Autorisierungsendpunkt zurückgegebenen Codes an.
oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
MapInboundClaims und die Konfiguration von NameClaimType und RoleClaimType: Viele OIDC-Server verwenden name und role anstelle der Standardwerte für SOAP/WS-Fed in ClaimTypes. Wenn MapInboundClaims auf false festgelegt ist, führt der Handler keine Anspruchszuordnungen durch, und die Anspruchsnamen aus dem JWT werden direkt von der App verwendet. Im folgenden Beispiel wird der Rollenanspruchstyp auf roles festgelegt, was für Microsoft Entra ID (ME-ID) geeignet ist. Weitere Informationen finden Sie in der Dokumentation Ihres Identitätsanbieters.
Note
MapInboundClaims muss für die meisten OIDC-Anbieter auf false festgelegt werden, um das Umbenennen von Ansprüchen zu verhindern.
oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = "name";
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
Pfadkonfiguration: Die Pfade müssen mit den bei der Registrierung der Anwendung beim OIDC-Anbieter konfigurierten Pfaden für den Umleitungs-URI (Login-Rückrufpfad) und für die Umleitung nach der Abmeldung (Abmelde-Rückrufpfad) übereinstimmen. Im Azure-Portal werden Pfade auf dem Blatt Authentifizierung der App-Registrierung konfiguriert. Sowohl die Anmelde- als auch die Abmeldepfade müssen als Umleitungs-URIs registriert werden. Die Standardwerte sind /signin-oidc und /signout-callback-oidc.
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signin-oidc
Note
Bei Verwendung von Microsoft Entra ID ist für localhost kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
SignedOutCallbackPath (Konfigurationsschlüssel: "SignedOutCallbackPath"): Der Anforderungspfad innerhalb des Basispfads der App, der vom OIDC-Handler abgefangen wird, wo der Benutzer-Agent nach der Abmeldung vom Identitätsanbieter zuerst zurückgeleitet wird. Die Beispiel App legt keinen Wert für den Pfad fest, da der Standardwert "/signout-callback-oidc" verwendet wird. Nach dem Abfangen der Anfrage leitet der OIDC Handler auf die SignedOutRedirectUri oder RedirectUri um, falls angegeben.
Konfigurieren Sie den Abmeldungs-Rückrufpfad in der OIDC-Anbieterregistrierung der App. Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost:{PORT}/signout-callback-oidc
Note
Legen Sie bei Verwendung der Microsoft Entra-ID den Pfad in den Redirect URI-Konfigurationseinträgen der Web-Plattform im Entra- oder Azure-Portal fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port. Wenn Sie den Rückrufpfad-URI für abgemeldete Benutzer nicht zur Registrierung der App bei Entra hinzufügen, lehnt Entra die Weiterleitung des Benutzers an die App ab und fordert ihn lediglich auf, das Browserfenster zu schließen.
RemoteSignOutPath: Anforderungen, die unter diesem Pfad empfangen werden, veranlassen den Handler, die Abmeldung mithilfe des Abmeldeschemas auszulösen.
Im folgenden Beispiel steht der {PORT} Platzhalter für den Port der App:
https://localhost/signout-oidc
Note
Wenn Sie Microsoft Entra ID verwenden, legen Sie im Entra- oder Azure-Portal die Front-Channel Logout URL fest. Bei der Verwendung von Entra ist für localhost-Adressen kein Port erforderlich. Die meisten anderen OIDC-Anbieter benötigen den richtigen Port.
oidcOptions.CallbackPath = new PathString("{PATH}");
oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
Beispiele (Standardwerte):
oidcOptions.CallbackPath = new PathString("/signin-oidc");
oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
(Microsoft Azure nur mit dem Endpunkt „common“) TokenValidationParameters.IssuerValidator: Viele OIDC-Anbieter arbeiten mit dem Standardaussteller-Validierer. Wir müssen jedoch den Aussteller berücksichtigen, der mit der von {TENANT ID} zurückgegebenen Mandanten-ID (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) parametrisiert ist. Weitere Informationen finden Sie unter SecurityTokenInvalidIssuerException bei OpenID Connect und beim Azure AD-Endpunkt „common“ (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).
Nur für Apps, die Microsoft Entra ID oder Azure AD B2C mit dem Endpunkt „common“ verwenden:
var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
Clientseitiges Blazor Web App Projekt (BlazorWebAppOidc.Client)
Das BlazorWebAppOidc.Client-Projekt ist das clientseitige Projekt des Blazor Web App.
Der Client ruft AddAuthenticationStateDeserialization auf, um den vom Server übergebenen Authentifizierungsstatus zu deserialisieren und zu verwenden. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
Die Klasse PersistentAuthenticationStateProvider (PersistentAuthenticationStateProvider.cs) ist ein clientseitiges AuthenticationStateProvider-Element, das den Authentifizierungsstatus der Benutzer bzw. Benutzerinnen bestimmt, indem nach Daten gesucht wird, die auf der Seite gespeicherten wurden, als diese auf dem Server gerendert wurde. Der Authentifizierungsstatus wird für die Lebensdauer der WebAssembly-Anwendung festgelegt.
Wenn sich Benutzer bzw. Benutzerinnen an- oder abmelden muss, muss die Seite vollständig neu geladen werden.
Die Beispiel-App stellt nur einen Benutzernamen und eine E-Mail für die Anzeige bereit.
Nur den Namen und die Rollenansprüche serialisieren
Dieser Abschnitt gilt nur für das Nicht-BFF-Muster (Interactive Auto) und das BFF-Muster (Interactive Auto) und deren Beispiel-Apps.
In der Program-Datei werden alle Claims serialisiert, indem SerializeAllClaims auf true gesetzt wird. Wenn Sie nur die Namens- und Rollenansprüche für CSR serialisiert haben möchten, entfernen Sie die Option oder setzen Sie sie auf false.
Liefern Sie die Konfiguration mit dem JSON-Konfigurationsanbieter
Die Beispiellösungsprojekte konfigurieren die OIDC- und JWT-Bearerauthentifizierung in ihren Program Dateien, um Konfigurationseinstellungen mithilfe von C#-AutoVervollständigen auffindbar zu machen. Professionelle Apps verwenden in der Regel einen Konfigurationsanbieter , um OIDC-Optionen zu konfigurieren, z. B. den standardmäßigen JSON-Konfigurationsanbieter. Der JSON-Konfigurationsanbieter lädt die Konfiguration aus App-Einstellungsdateien appsettings.json/appsettings.{ENVIRONMENT}.json, wobei der {ENVIRONMENT} Platzhalter die Laufzeitumgebung der App ist. Befolgen Sie die Anweisungen in diesem Abschnitt, um App-Einstellungsdateien für die Konfiguration zu verwenden.
Fügen Sie in der App-Einstellungsdatei (appsettings.json) des BlazorWebAppOidc- oder BlazorWebAppOidcServer-Projekts die folgende JSON-Konfiguration hinzu:
"Authentication": {
"Schemes": {
"MicrosoftOidc": {
"Authority": "https://login.microsoftonline.com/{TENANT ID (BLAZOR APP)}/v2.0",
"ClientId": "{CLIENT ID (BLAZOR APP)}",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc",
"RemoteSignOutPath": "/signout-oidc",
"SignedOutRedirectUri": "/",
"Scope": [
"openid",
"profile",
"offline_access",
"{APP ID URI (WEB API)}/Weather.Get"
]
}
}
},
Aktualisieren Sie die Platzhalter in der vorherigen Konfiguration so, dass sie den Werten entsprechen, die die App in der Program Datei verwendet:
-
{TENANT ID (BLAZOR APP)}: Die Mandanten-ID der App Blazor. -
{CLIENT ID (BLAZOR APP)}: Die Client-ID der Blazor App. -
{APP ID URI (WEB API)}: Der App-ID-URI der Web-API.
Die gemeinsame Autorität (https://login.microsoftonline.com/common/v2.0) sollte für Mehrinstanzen-Apps verwendet werden. Informationen zur Verwendung der "allgemeinen" Autorität für Einzelmandanten-Apps finden Sie im Abschnitt "Verwenden der gemeinsamen" Autorität für Einzelmandanten-Apps .
Aktualisieren Sie alle anderen Werte in der vorherigen Konfiguration so, dass sie mit benutzerdefinierten/nicht standardmäßigen Werten übereinstimmen, die in der Program Datei verwendet werden.
Die Konfiguration wird automatisch vom Authentifizierungs-Generator aufgenommen.
Entfernen Sie die folgenden Zeilen aus der Program Datei:
- oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
- oidcOptions.Scope.Add("...");
- oidcOptions.CallbackPath = new PathString("...");
- oidcOptions.SignedOutCallbackPath = new PathString("...");
- oidcOptions.RemoteSignOutPath = new PathString("...");
- oidcOptions.Authority = "...";
- oidcOptions.ClientId = "...";
Entfernen Sie in der ConfigureCookieOidc Methode von CookieOidcServiceCollectionExtensions.cs, die folgende Zeile:
- oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
Fügen Sie im MinimalApiJwt Projekt die folgende App-Einstellungen-Konfiguration in die appsettings.json Datei hinzu.
"Authentication": {
"Schemes": {
"Bearer": {
"Authority": "https://sts.windows.net/{TENANT ID (WEB API)}",
"ValidAudiences": [ "{APP ID URI (WEB API)}" ]
}
}
},
Aktualisieren Sie die Platzhalter in der vorherigen Konfiguration so, dass sie den Werten entsprechen, die die App in der Program Datei verwendet:
-
{TENANT ID (WEB API)}: Die Mandanten-ID der Web-API. -
{APP ID URI (WEB API)}: Der App-ID-URI der Web-API.
Autoritative Stellen übernehmen die folgenden Muster:
- ME-ID Mandantentyp:
https://sts.windows.net/{TENANT ID} - Externe Microsoft Entra-ID:
https://{DIRECTORY NAME}.ciamlogin.com/{TENANT ID}/v2.0 - B2C-Mandantentyp
https://login.microsoftonline.com/{TENANT ID}/v2.0
Zielgruppenformate übernehmen die folgenden Muster ({CLIENT ID} ist die Client-ID der Web-API; {DIRECTORY NAME} ist der Verzeichnisname, zum Beispiel contoso).
- ME-ID Mandantentyp:
api://{CLIENT ID} - Externe Microsoft Entra-ID:
{CLIENT ID} - B2C-Mandantentyp
https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
Die Konfiguration wird automatisch vom JWT-Bearerauthentifizierungs-Generator aufgenommen.
Entfernen Sie die folgenden Zeilen aus der Program Datei:
- jwtOptions.Authority = "...";
- jwtOptions.Audience = "...";
Weitere Informationen zur Konfiguration finden Sie in den folgenden Ressourcen:
Verwenden Sie die gebräuchliche Autorität für Einzelmandanten-Apps
Sie können die "übliche" Autorität für Einzelmandanten-Apps verwenden, aber Sie müssen die folgenden Schritte ausführen, um einen benutzerdefinierten Issuer-Validator zu implementieren.
Fügen Sie das Microsoft.IdentityModel.Validators NuGet-Paket zum BlazorWebAppOidc, BlazorWebAppOidcServer oder BlazorWebAppOidcBff-Projekt hinzu.
Note
Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Machen Sie oben in der Datei Program den Namespace Microsoft.IdentityModel.Validators verfügbar:
using Microsoft.IdentityModel.Validators;
Verwenden Sie den folgenden Code in der Datei, in der Program OIDC-Optionen konfiguriert sind:
var microsoftIssuerValidator =
AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
oidcOptions.TokenValidationParameters.IssuerValidator =
microsoftIssuerValidator.Validate;
Weitere Informationen finden Sie unter SecurityTokenInvalidIssuerException bei OpenID Connect und beim Azure AD-Endpunkt „common“ (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).
Beim Abmelden auf die Startseite umgeleitet
Die LogInOrOut Komponente (Layout/LogInOrOut.razor) legt ein verstecktes Feld für die Rückgabe-URL (ReturnUrl) auf die aktuelle URL (currentURL) fest. Wenn sich der Benutzer von der App abmeldet, leitet der Identitätsanbieter den Benutzer auf die Seite zurück, von der er sich abgemeldet hat. Wenn sich der Benutzer von einer sicheren Seite aus abmeldet, wird er auf dieselbe sichere Seite zurückgeleitet und durch den Authentifizierungsprozess zurückgeschickt. Dieser Flow zur Authentifizierung ist sinnvoll, wenn Benutzer regelmäßig ihre Konten wechseln müssen.
Verwenden Sie alternativ die folgende LogInOrOut Komponente, die beim Abmelden keine Rückgabe-URL liefert.
Layout/LogInOrOut.razor:
<div class="nav-item px-3">
<AuthorizeView>
<Authorized>
<form action="authentication/logout" method="post">
<AntiforgeryToken />
<button type="submit" class="nav-link">
<span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true">
</span> Logout
</button>
</form>
</Authorized>
<NotAuthorized>
<a class="nav-link" href="authentication/login">
<span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span>
Login
</a>
</NotAuthorized>
</AuthorizeView>
</div>
Tokenaktualisierung
Die benutzerdefinierte cookie Aktualisierungsimplementierung (CookieOidcRefresher.cs) aktualisiert die Ansprüche des Benutzers automatisch, wenn sie ablaufen. Die aktuelle Implementierung erwartet, dass ein ID-Token vom Tokenendpunkt im Austausch für das Aktualisierungstoken empfangen wird. Die Ansprüche in diesem ID-Token werden dann verwendet, um die Ansprüche des Benutzers zu überschreiben.
Die Beispielimplementierung enthält keinen Code zum Anfordern von Ansprüchen vom UserInfo-Endpunkt bei der Tokenaktualisierung. Weitere Informationen finden Sie unter BlazorWebAppOidc AddOpenIdConnect with GetClaimsFromUserInfoEndpoint = true doesn't propogate [sic] role claims to client (dotnet/aspnetcore #58826).
Note
Einige Identitätsanbieter geben nur ein Zugriffstoken zurück, wenn ein Aktualisierungstokenverwendet wird. Die CookieOidcRefresher kann mit zusätzlicher Logik aktualisiert werden, um weiterhin den vorherigen Satz von Ansprüchen zu verwenden, die in der Authentifizierung cookie gespeichert sind, oder das Zugriffstoken zu nutzen, um Ansprüche über den UserInfo-Endpunkt anzufordern.
Kryptografische Nonce
Eine Nonce ist ein Zeichenfolgenwert, die die Sitzung eines Clients mit einem ID-Token verknüpft, um Replay-Angriffe zu verhindern.
Wenn Sie während der Authentifizierungsentwicklung und -tests einen Nonce-Fehler erhalten, verwenden Sie für jede Testausführung eine neue InPrivate/Inkognito-Browsersitzung, unabhängig davon, wie klein die Änderung an der App oder dem Testbenutzer ist, da veraltete cookie Daten zu einem Nonce-Fehler führen können. Weitere Informationen finden Sie im Abschnitt Cookies und Standortdaten.
Eine Nonce ist nicht erforderlich oder wird nicht verwendet, wenn ein Aktualisierungstoken für ein neues Zugriffstoken ausgetauscht wird. In der Beispiel-App setzt CookieOidcRefresher (CookieOidcRefresher.cs) absichtlich OpenIdConnectProtocolValidator.RequireNonce auf false.
Anwendungsrollen für Apps, die nicht bei Microsoft Entra registriert sind (ME-ID)
Dieser Abschnitt bezieht sich auf Apps, die nicht Microsoft Entra ID (ME-ID) als Identitätsanbieter verwenden. Informationen zu Apps, die bei ME-ID registriert sind, finden Sie im Abschnitt Anwendungsrollen für Apps, die bei Microsoft Entra (ME-ID) registriert sind.
Konfigurieren Sie die Rolle Anspruchstyp (TokenValidationParameters.RoleClaimType) in der OpenIdConnectOptions von Program.cs:
oidcOptions.TokenValidationParameters.RoleClaimType = "{ROLE CLAIM TYPE}";
Bei vielen OIDC-Identitätsanbietern ist der Rollenanspruchstyp role. Überprüfen Sie die Dokumentation Ihres Identitätsanbieters auf den richtigen Wert.
Ersetzen Sie die UserInfo-Klasse im BlazorWebAppOidc.Client-Projekt durch die folgende Klasse.
UserInfo.cs:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using System.Security.Claims;
namespace BlazorWebAppOidc.Client;
// Add properties to this class and update the server and client
// AuthenticationStateProviders to expose more information about
// the authenticated user to the client.
public sealed class UserInfo
{
public required string UserId { get; init; }
public required string Name { get; init; }
public required string[] Roles { get; init; }
public const string UserIdClaimType = "sub";
public const string NameClaimType = "name";
private const string RoleClaimType = "role";
public static UserInfo FromClaimsPrincipal(ClaimsPrincipal principal) =>
new()
{
UserId = GetRequiredClaim(principal, UserIdClaimType),
Name = GetRequiredClaim(principal, NameClaimType),
Roles = principal.FindAll(RoleClaimType).Select(c => c.Value)
.ToArray(),
};
public ClaimsPrincipal ToClaimsPrincipal() =>
new(new ClaimsIdentity(
Roles.Select(role => new Claim(RoleClaimType, role))
.Concat([
new Claim(UserIdClaimType, UserId),
new Claim(NameClaimType, Name),
]),
authenticationType: nameof(UserInfo),
nameType: NameClaimType,
roleType: RoleClaimType));
private static string GetRequiredClaim(ClaimsPrincipal principal,
string claimType) =>
principal.FindFirst(claimType)?.Value ??
throw new InvalidOperationException(
$"Could not find required '{claimType}' claim.");
}
Für Razor-Komponenten ist nun rollenbasierte und richtlinienbasierte Autorisierung möglich. Anwendungsrollen erscheinen in role Claims, ein Claim pro Rolle.
Anwendungsrollen für Apps, die bei Microsoft Entra (ME-ID) registriert sind
Befolgen Sie die Anleitungen in diesem Abschnitt, um Anwendungsrollen, ME-ID-Sicherheitsgruppen und integrierte ME-ID-Adminrollen für Apps mit Microsoft Entra ID (ME-ID) zu implementieren.
Der in diesem Abschnitt beschriebene Ansatz konfiguriert ME-ID so, dass Gruppen und Rollen im Authentifizierungs-Header cookie gesendet werden. Wenn Benutzende nur Mitglied einiger weniger Sicherheitsgruppen und -rollen sind, sollte der folgende Ansatz für die meisten Hosting-Plattformen funktionieren, ohne dass es zu Problemen mit zu langen Headern kommt, z. B. bei IIS-Hosting, das über eine Standard-Header-Längenbegrenzung von 16 KB (MaxRequestBytes) verfügt. Wenn die Länge des Headers aufgrund einer hohen Anzahl an Gruppen- oder Rollenmitgliedschaften ein Problem darstellt, empfehlen wir, die Anleitung in diesem Abschnitt nicht zu befolgen und stattdessen Microsoft Graph zu implementieren, um die Gruppen und Rollen von Benutzenden separat von der ME-ID abzurufen. Dieser Ansatz führt nicht zu einer Vergrößerung der Authentifizierung cookie. Weitere Informationen finden Sie unter Ungültige Anforderung – Anforderung zu lang – IIS-Server (dotnet/aspnetcore #57545).
Konfigurieren Sie den Rollenanspruchstyp (TokenValidationParameters.RoleClaimType) in OpenIdConnectOptions von Program.cs. Legen Sie den Wert auf roles fest:
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
Zwar können Sie ohne ME-ID-Premium-Konto nicht Rollen zu Gruppen zuweisen, aber Sie können Benutzenden Rollen zuweisen und Rollenansprüche für Benutzende mit einem Azure-Standardkonto erhalten. Für die Schritte in diesem Abschnitt ist kein ME-ID Premium-Konto erforderlich.
Befolgen Sie beim Arbeiten mit dem Standardverzeichnis die Anweisungen unter Anwendungsrollen zu Ihrer Anwendung hinzufügen und im Token empfangen (ME-ID-Dokumentation), um Rollen zu konfigurieren und zuzuweisen. Wenn Sie nicht mit dem Standardverzeichnis arbeiten, bearbeiten Sie das Manifest der App im Azure-Portal, um die Rollen der App manuell im appRoles-Eintrag der Manifestdatei einzurichten. Weitere Informationen finden Sie unter Konfigurieren des Rollenanspruchs (ME-ID-Dokumentation).
Die Azure-Sicherheitsgruppen eines Benutzers kommen in groups -Ansprüchen an, und die integrierten ME-ID-Administratorrollenzuweisungen eines Benutzers kommen in Wohlbekannte IDs (wids) Ansprüchenan. Die Werte für beide Anspruchsarten sind GUIDs. Wenn sie von der App empfangen werden, können diese Claims verwendet werden, um die Rollen- und Richtlinienautorisierung in Razor Komponenten einzurichten.
Legen Sie im Azure-Portal im App-Manifest das groupMembershipClaims-Attribut auf All fest. Beim Wert All sendet ME-ID alle Sicherheits-/Verteilergruppen (groups-Ansprüche) und Rollen (wids-Ansprüche) der angemeldeten Benutzenden. Um das groupMembershipClaims-Attribut festzulegen:
- Öffnen Sie die App-Registrierungen im Azure-Portal.
- Wählen Sie in der Randleiste Verwalten>Manifest aus.
- Suchen Sie das
groupMembershipClaims-Attribut. - Legen Sie den Wert auf
Allfest ("groupMembershipClaims": "All"). - Wählen Sie die Schaltfläche Speichern aus.
Ersetzen Sie die UserInfo-Klasse im BlazorWebAppOidc.Client-Projekt durch die folgende Klasse.
UserInfo.cs:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using System.Security.Claims;
namespace BlazorWebAppOidc.Client;
// Add properties to this class and update the server and client
// AuthenticationStateProviders to expose more information about
// the authenticated user to the client.
public sealed class UserInfo
{
public required string UserId { get; init; }
public required string Name { get; init; }
public required string[] Roles { get; init; }
public required string[] Groups { get; init; }
public required string[] Wids { get; init; }
public const string UserIdClaimType = "sub";
public const string NameClaimType = "name";
private const string RoleClaimType = "roles";
private const string GroupsClaimType = "groups";
private const string WidsClaimType = "wids";
public static UserInfo FromClaimsPrincipal(ClaimsPrincipal principal) =>
new()
{
UserId = GetRequiredClaim(principal, UserIdClaimType),
Name = GetRequiredClaim(principal, NameClaimType),
Roles = principal.FindAll(RoleClaimType).Select(c => c.Value)
.ToArray(),
Groups = principal.FindAll(GroupsClaimType).Select(c => c.Value)
.ToArray(),
Wids = principal.FindAll(WidsClaimType).Select(c => c.Value)
.ToArray(),
};
public ClaimsPrincipal ToClaimsPrincipal() =>
new(new ClaimsIdentity(
Roles.Select(role => new Claim(RoleClaimType, role))
.Concat(Groups.Select(role => new Claim(GroupsClaimType, role)))
.Concat(Wids.Select(role => new Claim(WidsClaimType, role)))
.Concat([
new Claim(UserIdClaimType, UserId),
new Claim(NameClaimType, Name),
]),
authenticationType: nameof(UserInfo),
nameType: NameClaimType,
roleType: RoleClaimType));
private static string GetRequiredClaim(ClaimsPrincipal principal,
string claimType) =>
principal.FindFirst(claimType)?.Value ??
throw new InvalidOperationException(
$"Could not find required '{claimType}' claim.");
}
Für Razor-Komponenten ist nun rollenbasierte und richtlinienbasierte Autorisierung möglich:
- Anwendungsrollen erscheinen in
rolesClaims, ein Claim pro Rolle. - Sicherheitsgruppen werden in
groups-Claims angezeigt – ein Claim pro Gruppe. Die Sicherheitsgruppen-GUIDs werden im Azure-Portal angezeigt, wenn Sie eine Sicherheitsgruppe erstellen, und sie werden aufgelistet, wenn Sie Identity>Übersicht>Gruppen>Ansicht auswählen. - Eingebaute ME-ID-Administratorrollen erscheinen in
wids-Ansprüchen, ein Anspruch pro Rolle. Derwids-Anspruch mit einem Wert vonb79fbf4d-3ef9-4689-8143-76b194e85509wird immer von ME-ID für Nicht-Gastkonten der Mandantin bzw. des Mandanten gesendet und verweist nicht auf eine Adminrolle. Adminrollen-GUIDs (Rollenvorlagen-IDs) werden im Azure-Portal angezeigt, wenn Sie Rollen und Administratoren auswählen, gefolgt von den Auslassungspunkten (...) >Beschreibung für die aufgeführte Rolle. Die IDs der Rollenvorlagen sind auch in Microsoft Entra integrierte Rollen (Entra Dokumentation)aufgeführt.
Alternative: Duende Zugriffstokenverwaltung
In der Beispiel-App wird eine benutzerdefinierte cookie Aktualisierungsimplementierung (CookieOidcRefresher.cs) verwendet, um eine automatische, nicht interaktive Tokenaktualisierung durchzuführen. Eine alternative Lösung finden Sie im Open-Source-Paket.
Die Duende-Zugriffstokenverwaltung bietet automatische Zugriffstoken-Verwaltungsfunktionen für .NET-Worker und ASP.NET Core-Web-Apps, einschließlich Blazor, ohne dass ein benutzerdefinierter cookie Aktualisierer hinzugefügt werden muss.
Nach der Installation des Pakets entfernen Sie CookieOidcRefresher und fügen Sie die Zugriffstokenverwaltung für den aktuell angemeldeten Benutzer in der Program Datei hinzu.
// Add services for token management
builder.Services.AddOpenIdConnectAccessTokenManagement();
// Register a typed HTTP client with token management support
builder.Services.AddHttpClient<InvoiceClient>(client =>
{
client.BaseAddress = new Uri("https://api.example.com/invoices/");
})
.AddUserAccessTokenHandler();
Der typisierte HTTP-Client (oder der benannte HTTP-Client, falls implementiert) verfügt über die automatische Verwaltung der Lebensdauer von Zugriffstokens im Namen des derzeit angemeldeten Benutzers, einschließlich der transparenten Verwaltung von Aktualisierungstokens.
Weitere Informationen finden Sie in der Dokumentation zur Duende-Zugriffstokenverwaltung für Blazor.
Troubleshoot
Logging
Die Server-App ist eine Standard-ASP.NET Core-App. Weitere Informationen finden Sie in den ASP.NET Core-Protokollierungsanleitungen zum Aktivieren einer niedrigeren Protokollierungsebene in der Server-App.
Um Debuggen oder Ablaufprotokollierung für die Blazor WebAssembly Authentifizierung zu aktivieren, siehe den Abschnitt Clientseitige Authentifizierungsprotokollierung von ASP.NET Core Blazor Protokollierung mit dem Artikelversionsselektor, der auf ASP.NET Core in .NET 7 oder höher eingestellt ist.
Häufige Fehler
Debugger bricht bei einer Ausnahme während der Abmeldung mit Microsoft Entra External ID ab
Die folgende Ausnahme stoppt den Visual Studio-Debugger während der Abmeldung mit der externen Microsoft Entra-ID:
Uncaught TypeError TypeError: Failed to execute 'postMessage' on 'Window': The provided value cannot be converted to a sequence.
Die Ausnahme wird aus Entra-JavaScript-Code ausgelöst, daher ist dies kein Problem mit ASP.NET Core. Die Ausnahme wirkt sich nicht auf die App-Funktionalität in der Produktion aus, sodass die Ausnahme während der lokalen Entwicklungstests ignoriert werden kann.
Falsche Konfiguration der App oder des Identity-Anbieters (IP)
Die häufigsten Fehler werden durch eine falsche Konfiguration verursacht. Im Folgenden finden Sie einige Beispiele:
- In Abhängigkeit von den Anforderungen des Szenarios verhindert eine fehlende oder falsche Autorität, Instanz, Mandanten-ID, Mandantendomäne oder Client-ID oder ein fehlender oder falscher Umleitungs-URI, dass Clients von einer App authentifiziert werden.
- Falsche Anforderungsbereiche verhindern, dass Clients auf die Web-API-Endpunkte des Servers zugreifen können.
- Falsche oder fehlende Server-API-Berechtigungen verhindern, dass Clients auf Server-Web-API-Endpunkte zugreifen können.
- Das Ausführen der App an einem anderen Port als dem, der im Umleitungs-URI der App-Registrierung für die IP konfiguriert ist. Beachten Sie, dass für Microsoft Entra ID und eine App, die an einer
localhost-Entwicklungstestadresse ausgeführt wird, kein Port erforderlich ist. Die Portkonfiguration der App und der Port, an dem die App ausgeführt wird, müssen jedoch für Nicht-localhost-Adressen übereinstimmen.
Die Konfigurationsabdeckung in diesem Artikel enthält Beispiele für die richtige Konfiguration. Überprüfen Sie sorgfältig die Konfiguration auf App- und IP-Fehlkonfigurationen.
Wenn die Konfiguration anscheinend korrekt ist:
Analysieren Sie Anwendungsprotokolle.
Überprüfen Sie den Netzwerkdatenverkehr zwischen der Client-App und dem IP oder der Server-App mit den Entwicklertools des Browsers. Häufig gibt die IP oder die Server-Anwendung eine genaue Fehlermeldung oder eine Meldung mit einem Hinweis auf die Ursache des Problems an den Client zurück, nachdem eine Anfrage gestellt wurde. Anleitungen zu den Entwicklertools finden Sie in den folgenden Artikeln:
- Google Chrome (Google-Dokumentation)
- Microsoft Edge
- Mozilla Firefox (Mozilla-Dokumentation)
Das Dokumentationsteam berücksichtigt Feedback zur Dokumentation und zu Fehlern in Artikeln. (Legen Sie im Feedbackbereich auf dieser Seite ein Ticket an.) Es leistet jedoch keinen Produktsupport. Es gibt einige öffentliche Supportforen, die bei der Problembehandlung für eine App weiterhelfen. Es wird Folgendes empfohlen:
Die genannten Foren werden nicht von Microsoft betrieben oder kontrolliert.
Bei nicht sicherheitsbezogenen, nicht sensiblen und nicht vertraulichen Fehlerberichten zum Framework wird legen Sie ein Ticket für die ASP.NET Core-Produkteinheit an. Legen Sie ein Ticket für die Produkteinheit erst an, wenn Sie die Ursache eines Problems gründlich untersucht haben und es nicht selbst oder mithilfe der Community in einem öffentlichen Supportforum lösen konnten. Die Produkteinheit kann keine Problembehandlung für einzelne Apps durchführen, die aufgrund einer einfachen Fehlkonfiguration oder in Anwendungsfällen mit Drittanbieterdiensten nicht funktionieren. Wenn ein Bericht sensibler oder vertraulicher Natur ist oder eine potenzielle Sicherheitslücke im Produkt beschreibt, die von Cyberkriminellen ausgenutzt werden könnte, lesen Sie bitte Melden von Sicherheitsproblemen und Fehlern (
dotnet/aspnetcoreGitHub Repository).Nicht autorisierter Client für ME-ID
Info: Die Autorisierung von Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization ist fehlgeschlagen. Diese Anforderungen wurden nicht erfüllt: DenyAnonymousAuthorizationRequirement: Erfordert einen authentifizierten Benutzer.
Anmelderückruffehler von ME-ID:
- Fehler:
unauthorized_client - Description (Beschreibung):
AADB2C90058: The provided application is not configured to allow public clients.
So beheben Sie den Fehler
- Greifen Sie im Azure-Portal auf das Manifest der App zu.
- Legen Sie das
allowPublicClient-Attribut aufnullodertruefest.
- Fehler:
Cookies und Standortdaten
Cookies und Standortdaten können über App-Updates hinweg beibehalten werden und das Testen und die Problembehandlung beeinträchtigen. Entfernen Sie Folgendes, wenn Sie Änderungen am App-Code, Änderungen an den Benutzerkonten beim Anbieter oder Konfigurationsänderungen an Anbieter-Apps vornehmen:
- Anmelde-Cookies von Benutzern
- App-Cookies
- Zwischengespeicherte und gespeicherte Standortdaten
Ein Ansatz, um zu verhindern, dass veraltete Cookies und Standortdaten das Testen und die Problembehandlung beeinträchtigen, ist folgender:
- Browser konfigurieren
- Verwenden Sie zum Testen einen Browser, den Sie so konfigurieren können, dass alle cookies und Standortdaten jedes Mal gelöscht werden, wenn der Browser geschlossen wird.
- Stellen Sie sicher, dass der Browser manuell oder durch die IDE für alle Änderungen an der App, dem Testbenutzer oder der Anbieterkonfiguration geschlossen wird.
- Verwenden Sie einen benutzerdefinierten Befehl, um in Visual Studio einen Browser im privaten oder Inkognito-Modus zu öffnen:
- Öffnen Sie das Dialogfeld Browse With mit der Schaltfläche Ausführen von Visual Studio.
- Wählen Sie die Schaltfläche Hinzufügen aus.
- Geben Sie im Feld Programm den Pfad zu Ihrem Browser an. Die folgenden Pfade für ausführbare Dateien sind typische Installationspfade für Windows 10. Wenn Ihr Browser an einem anderen Speicherort installiert ist oder Sie nicht Windows 10 verwenden, geben Sie den Pfad zur ausführbaren Datei des Browsers an.
- Microsoft Edge:
C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe - Google Chrome:
C:\Program Files (x86)\Google\Chrome\Application\chrome.exe - Mozilla Firefox:
C:\Program Files\Mozilla Firefox\firefox.exe
- Microsoft Edge:
- Geben Sie im Feld Argumente die Befehlszeilenoption an, die der Browser verwendet, um im privaten oder Inkognito-Modus geöffnet zu werden. Für einige Browser ist die URL der App erforderlich.
- Microsoft Edge: Verwenden Sie
-inprivate. - Google Chrome: Verwenden Sie
--incognito --new-window {URL}, wobei der Platzhalter{URL}die zu öffnende URL ist (z. B.https://localhost:5001). - Mozilla Firefox: Verwenden Sie
-private -url {URL}, wobei der Platzhalter{URL}die zu öffnende URL ist (z. B.https://localhost:5001).
- Microsoft Edge: Verwenden Sie
- Geben Sie im Feld Freundlicher Name einen Namen ein. Beispielsweise
Firefox Auth Testing. - Klicken Sie auf die Schaltfläche OK.
- Um zu vermeiden, dass das Browserprofil für jede einzelne Testiteration einer App ausgewählt werden muss, legen Sie das Profil mithilfe der Schaltfläche Als Standard festlegen als Standard fest.
- Stellen Sie sicher, dass der Browser von der IDE für alle Änderungen an der App, dem Testbenutzer oder der Anbieterkonfiguration geschlossen wird.
App-Upgrades
Eine funktionierende App kann unmittelbar nach dem Upgrade des .NET SDK auf dem Entwicklungscomputer oder beim Ändern von Paketversionen innerhalb der App fehlschlagen. In einigen Fällen können inkohärente Pakete eine App beschädigen, wenn größere Upgrades durchgeführt werden. Die meisten dieser Probleme können durch Befolgung der folgenden Anweisungen behoben werden:
- Löschen Sie die Caches für NuGet-Pakete auf dem lokalen System, indem Sie
dotnet nuget locals all --clearin einer Befehlsshell ausführen. - Löschen Sie die Ordner
binundobjdes Projekts. - Stellen Sie das Projekt wieder her und erstellen Sie es neu.
- Löschen Sie alle Dateien im Bereitstellungsordner auf dem Server, bevor Sie die App noch mal bereitstellen.
Note
Die Verwendung von Paketversionen, die mit dem Zielframework der App nicht kompatibel sind, wird nicht unterstützt. Um Informationen zu einem Paket zu erhalten, verwenden Sie die NuGet Gallery.
Starten Sie die Lösung aus dem richtigen Projekt
Blazor Web Apps:
- Starten Sie für eines der BFF-Musterbeispiele (Back-End-for-Frontend) die Lösung aus dem
Aspire/Aspire.AppHostProjekt. - Starten Sie für eines der nicht-BFF strukturierten Beispiele die Lösung aus dem Server-Projekt.
Blazor Server:
Starten Sie die Lösung vom Serverprojekt.
Überprüfen des Benutzers
Die folgende UserClaims-Komponente kann direkt in Anwendungen verwendet werden oder als Grundlage für weitere Anpassungen dienen.
UserClaims.razor:
@page "/user-claims"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
<PageTitle>User Claims</PageTitle>
<h1>User Claims</h1>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li><b>@claim.Type:</b> @claim.Value</li>
}
</ul>
}
@code {
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
[CascadingParameter]
private Task<AuthenticationState>? AuthState { get; set; }
protected override async Task OnInitializedAsync()
{
if (AuthState == null)
{
return;
}
var authState = await AuthState;
claims = authState.User.Claims;
}
}
Weitere Ressourcen
-
AzureAD/microsoft-identity-webGitHub-Repository: Hilfreicher Leitfaden zum Implementieren von Microsoft Identity Web für Microsoft Entra ID und Azure Active Directory B2C für ASP.NET Core-Apps, einschließlich Links zu Beispiel-Apps und zugehöriger Azure-Dokumentation. Derzeit werden Blazor Web Apps in der Azure-Dokumentation nicht explizit angesprochen, aber die Einrichtung und Konfiguration einer Blazor Web App für ME-ID und Azure-Hosting ist die gleiche wie für jede ASP.NET Core-Web-App. -
AuthenticationStateProvider-Dienst - Verwaltung des Authentifizierungsstatus in Blazor Web Apps
-
Token während einer http-Anfrage im Blazor Interaktiven Server mit OIDC aktualisieren (
dotnet/aspnetcore#55213) - Sichere Daten in Blazor Web Apps mit interaktivem automatischen Rendering
-
Zugriff auf einen
AuthenticationStateProvideraus einemDelegatingHandler