Schützen einer Blazor-Web-App in ASP.NET Core mit OpenID Connect (OIDC)
In diesem Artikel wird beschrieben, wie Sie eine Blazor-Web-App mit OpenID Connect (OIDC) mithilfe einer Beispiel-App im GitHub-Repository dotnet/blazor-samples
(.NET 8 oder höher) (Downloadanleitung) schützen.
Diese Version des Artikels behandelt die Implementierung von OIDC, ohne dass das BFF-Muster (Back-End für Front-Ends) dafür übernommen wird. Das BFF-Muster ist nützlich, um authentifizierte Anforderungen an externe Dienste zu senden. Ändern Sie die Artikelversionsauswahl in OIDC mit BFF-Muster, wenn die Spezifikation der App das BFF-Muster vorsieht.
Die folgende Spezifikation wird behandelt:
- Die Blazor-Web-App verwendet den Rendermodus „Automatisch“ 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
- Ruft eine (Web)-API sicher im Serverprojekt für Daten auf.
Beispiel-App
Die Beispiel-App umfasst zwei Projekte:
BlazorWebAppOidc
: Serverseitiges Projekt der Blazor-Web-App, das einen Beispielendpunkt für die Minimal-API für Wetterdaten enthältBlazorWebAppOidc.Client
: Clientseitiges Projekt der Blazor-Web-App.
Sie können über den Repositorystamm über folgenden Link auf die Beispiel-Apps im neuesten Versionsordner zugreifen. Die Projekte für .NET 8 oder höher befinden sich im Ordner BlazorWebAppOidc
.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Serverseitiges Blazor-Web-App-Projekt (BlazorWebAppOidc
)
Das BlazorWebAppOidc
-Projekt ist das serverseitige Projekt der Blazor-Web-App.
Die Datei BlazorWebAppOidc.http
kann zum Testen der Wetterdatenanforderung verwendet werden. Beachten Sie, dass das BlazorWebAppOidc
-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.
Hinweis
Das Serverprojekt verwendet IHttpContextAccessor/HttpContext, jedoch nie für interaktiv gerenderte Komponenten. Weitere Informationen finden Sie im Leitfaden zur Bedrohungsabwehr für das interaktive serverseitige Rendering von ASP.NET Core Blazor.
Konfiguration
In diesem Abschnitt wird erläutert, wie Sie die Beispiel-App konfigurieren.
Hinweis
Für Microsoft Entra ID und Azure AD B2C können Sie AddMicrosoftIdentityWebApp aus Microsoft Identity Web (NuGet-Paket Microsoft.Identity.Web
, API-Dokumentation) verwenden. Damit werden der OIDC- und der Cookie-Authentifizierungshandler mit den entsprechenden Standardwerten hinzugefügt. Die Beispiel-App und die Anleitung in diesem Abschnitt verwenden nicht Microsoft Identity Web. 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 in den verknüpften Ressourcen.
Die folgende OpenIdConnectOptions-Konfiguration befindet sich in der Datei Program
des Projekts beim Aufruf von AddOpenIdConnect:
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
undprofile
(Scope) (Optional): Die Bereicheopenid
undprofile
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 derAuthentication: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 standardmäßig auf
false
festgelegt, um die Größe des endgültigen cookie-Elements für die Authentifizierung zu verringern.oidcOptions.SaveTokens = false;
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}";
Beispiel:
- Autorität (
{AUTHORITY}
):https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/
(verwendet Mandanten-IDa3942615-d115-4eb7-bc84-9974abcf5064
) - Client-ID (
{CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/"; oidcOptions.ClientId = "4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
Beispiel für die Autorität „common“ von Microsoft Azure:
Die Autorität „common“ sollte für mehrinstanzenfähige Apps 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/";
- Autorität (
ClientSecret: Der geheimer OIDC-Clientschlüssel
Das folgende Beispiel dient nur zu Test- und Demonstrationszwecken. Speichern Sie den geheimen Clientschlüssel nicht in der Assembly der App, und checken Sie den geheimen Schlüssel nicht in die Quellcodeverwaltung ein. Speichern Sie den geheimen Clientschlüssel unter Benutzergeheimnisse, in Azure Key Vault oder in einer Umgebungsvariablen.
Die Authentifizierungsschemakonfiguration wird automatisch aus
builder.Configuration["Authentication:Schemes:{SCHEME NAME}:{PropertyName}"]
gelesen. Dabei ist der Platzhalter{SCHEME NAME}
das Schema (standardmäßigMicrosoftOidc
). Da die Konfiguration vorkonfiguriert ist, kann ein geheimer Clientschlüssel automatisch über den KonfigurationsschlüsselAuthentication:Schemes:MicrosoftOidc:ClientSecret
gelesen werden. Benennen Sie auf dem Server mithilfe von Umgebungsvariablen die UmgebungsvariableAuthentication__Schemes__MicrosoftOidc__ClientSecret
:set Authentication__Schemes__MicrosoftOidc__ClientSecret={CLIENT SECRET}
Nur zu Demonstrations- und Testzwecken. ClientSecret kann direkt festgelegt werden. Legen Sie den Wert nicht direkt für bereitgestellte Produktions-Apps fest. Für etwas mehr Sicherheit müssen Sie die Zeile bedingt mit dem Symbol
DEBUG
kompilieren:#if DEBUG oidcOptions.ClientSecret = "{CLIENT SECRET}"; #endif
Beispiel:
Geheimer Clientschlüssel (
{CLIENT SECRET}
):463471c8c4...f90d674bc9
(für die Darstellung gekürzt)#if DEBUG oidcOptions.ClientSecret = "463471c8c4...137f90d674bc9"; #endif
ResponseType: Konfiguriert den OIDC-Handler so, dass nur der Autorisierungscodeflow ausgeführt wird. Implizite Genehmigungen und Hybridflows sind in diesem Modus nicht erforderlich.
Aktivieren Sie in der App-Registrierungskonfiguration Implizite Genehmigung und Hybridflows im Entra- oder Azure-Portal *keins der Kontrollkästchen für den Autorisierungsendpunkt, um Zugriffstoken oder ID-Token zurückzugeben. 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
undrole
anstelle der Standardwerte für SOAP/WS-Fed in ClaimTypes. Wenn MapInboundClaims auffalse
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 aufroles
festgelegt, wie für die Microsoft Entra-ID (ME-ID) passend. Weitere Informationen dazu können Sie der Identitätsanbieter-Dokumentation entnehmen.
Hinweis
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 = JwtRegisteredClaimNames.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 (Anmelderückrufpfad) und für die Umleitung nach der Abmeldung (abgemeldeter 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
Legen Sie im Entra- oder Azure-Portal den Pfad im Umleitungs-URI der Plattformkonfiguration für Web fest:
https://localhost/signin-oidc
Hinweis
Bei Verwendung von Microsoft Entra ID ist für
localhost
kein Port erforderlich. Die meisten anderen OIDC-Anbieter erfordern einen richtigen Port.SignedOutCallbackPath: Der Anforderungspfad innerhalb des Basispfads der App, in dem der Benutzer-Agent nach der Abmeldung vom Identitätsanbieter zurückgegeben wird
Legen Sie im Entra- oder Azure-Portal den Pfad im Umleitungs-URI der Plattformkonfiguration für Web fest:
https://localhost/signout-callback-oidc
Hinweis
Bei Verwendung von Microsoft Entra ID ist für
localhost
kein Port erforderlich. Die meisten anderen OIDC-Anbieter erfordern einen richtigen Port.Hinweis
Bei Verwendung von Microsoft Identity Web leitet der Anbieter derzeit nur zurück an SignedOutCallbackPath um, wenn
microsoftonline.com
die Autorität (https://login.microsoftonline.com/{TENANT ID}/v2.0/
) verwendet wird. Diese Einschränkung besteht nicht, wenn Sie die Autorität „common“ mit Microsoft Identity Web verwenden können. Weitere Informationen finden Sie unter postLogoutRedirectUri funktioniert nicht, wenn die Autoritäts-URL eine Mandanten-ID enthält (AzureAD/microsoft-authentication-library-for-js
#5783).RemoteSignOutPath: Unter diesem Pfad empfangene Anforderungen führen dazu, dass der Handler die Abmeldung mithilfe des Abmeldeschemas aufruft.
Legen Sie im Entra- oder Azure-Portal die URL für Front-Channel-Abmeldung fest:
https://localhost/signout-oidc
Hinweis
Bei Verwendung von Microsoft Entra ID ist für
localhost
kein Port erforderlich. Die meisten anderen OIDC-Anbieter erfordern einen 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-Validierungssteuerelement, wir müssen jedoch den Aussteller berücksichtigen, der mit der von
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
zurückgegebenen Mandanten-ID ({TENANT ID}
) 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;
Code der Beispiel-App
Sehen Sie sich die folgenden Features der Beispiel-App an:
- Automatische, nicht interaktive Tokenaktualisierung mithilfe einer benutzerdefinierten cookie-Aktualisierung (
CookieOidcRefresher.cs
) - 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. - Ein Beispiel für Anforderungen an die Blazor-Web-App für Wetterdaten wird von einem Endpunkt der Minimal-API (
/weather-forecast
) in der DateiProgram
(Program.cs
) 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. - Die App ruft eine (Web)-API im Serverprojekt sicher für Wetterdaten auf:
- Beim Rendern der
Weather
Komponente auf dem Server verwendet die Komponente denServerWeatherForecaster
server, um Wetterdaten direkt abzurufen (nicht über einen Web-API-Aufruf). - Wenn die Komponente auf dem Client gerendert wird, verwendet die Komponente die
ClientWeatherForecaster
Dienstimplementierung, 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 ServerprojektsProgram
definiert ist, ruft die Wetterdaten aus demServerWeatherForecaster
Und gibt die Daten an den Client zurück.
- Beim Rendern der
Weitere Informationen zu (Web)-API-Aufrufen mithilfe einer Dienstabstraktion in Blazor Web Apps finden Sie unter Aufrufen einer Web-API aus einer ASP.NET Core-App Blazor.
Clientseitiges Blazor-Web-App-Projekt (BlazorWebAppOidc.Client
)
Das BlazorWebAppOidc.Client
-Projekt ist das clientseitige Projekt der Blazor-Web-App.
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. Es sind keine Token enthalten, die sich beim Senden von nachfolgenden Anforderungen beim Server authentifizieren und separat mithilfe eines cookie-Elements aus den HttpClient-Anforderungen an den Server verarbeitet werden.
Diese Version des Artikels behandelt die Implementierung von OIDC mit dem BFF-Muster (Back-End für Front-Ends). Ändern Sie die Artikelversionsauswahl in OIDC ohne BFF-Muster, wenn die Spezifikation der App das BFF-Muster nicht vorsieht.
Die folgende Spezifikation wird behandelt:
- Die Blazor-Web-App verwendet den Rendermodus „Automatisch“ 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
- Das BFF-Muster (Back-End für Front-Ends) wird mithilfe von .NET Aspire für die Dienstermittlung und YARP für die Weiterleitung von Anforderungen per Proxy an einen Wettervorhersageendpunkt in der Back-End-App übernommen.
- Eine Back-End-Web-API verwendet die JWT-Bearer-Authentifizierung, um JWT-Token zu überprüfen, die von der Blazor-Web-App im cookie-Element für die Anmeldung gespeichert wurden.
- Aspire verbessert die Erfahrung beim Erstellen von cloudnativen .NET-Apps. Aspire bietet einen konsistenten, umfangreichen Satz von Tools und Mustern zum Erstellen und Ausführen verteilter Apps.
- YARP (Yet Another Reverse Proxy) ist eine Bibliothek, die zum Erstellen eines Reverseproxyservers verwendet wird.
Weitere Informationen zu .NET Aspire finden Sie unter General Availability of .NET Aspire: Simplifying .NET Cloud-Native Development (Mai 2024).
Voraussetzungen
.NET Aspire benötigt Visual Studio Version 17.10 oder höher.
Beispiel-App
Die Beispiel-App umfasst fünf Projekte:
- .NET Aspire:
Aspire.AppHost
: Wird zum Verwalten der allgemeinen Orchestrierungsaspekte der App verwendet.Aspire.ServiceDefaults
: Enthält standardmäßige .NET Aspire-App-Konfigurationen, die bei Bedarf erweitert und angepasst werden können.
MinimalApiJwt
: Back-End-Web-API mit einem Beispielendpunkt für die Minimal-API für Wetterdaten.BlazorWebAppOidc
: Serverseitiges Projekt der Blazor-Web-App.BlazorWebAppOidc.Client
: Clientseitiges Projekt der Blazor-Web-App.
Sie können über den Repositorystamm über folgenden Link auf die Beispiel-Apps im neuesten Versionsordner zugreifen. Die Projekte für .NET 8 oder höher befinden sich im Ordner BlazorWebAppOidcBff
.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
.NET Aspire-Projekte
Weitere Informationen zur Verwendung von .NET Aspire und Details zu den Projekten .AppHost
und .ServiceDefaults
der Beispiel-App finden Sie in der .NET Aspire-Dokumentation.
Vergewissern Sie sich, dass Sie die Voraussetzungen für .NET Aspire erfüllt haben. Weitere Informationen finden Sie im Abschnitt Voraussetzungen unter Schnellstartanleitung: Erstellen Ihrer ersten .NET Aspire-App.
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 Starteinstellungen, finden Sie unter Ungesicherten Transport in .NET Aspire (.NET Aspire-Dokumentation) zulassen.
Serverseitiges Blazor-Web-App-Projekt (BlazorWebAppOidc
)
Das BlazorWebAppOidc
-Projekt ist das serverseitige Projekt der Blazor-Web-App. Das Projekt nutzt YARP zum Weiterleiten von Anforderungen per Proxy an einen Wettervorhersageendpunkt im Back-End-Web-API-Projekt (MinimalApiJwt
). Das Zugriffstoken (access_token
) wird dabei im cookie-Element für die Authentifizierung gespeichert.
Die Datei BlazorWebAppOidc.http
kann zum Testen der Wetterdatenanforderung verwendet werden. Beachten Sie, dass das BlazorWebAppOidc
-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.
Hinweis
Das Serverprojekt verwendet IHttpContextAccessor/HttpContext, jedoch nie für interaktiv gerenderte Komponenten. Weitere Informationen finden Sie im Leitfaden zur Bedrohungsabwehr für das interaktive serverseitige Rendering von ASP.NET Core Blazor.
Konfiguration
In diesem Abschnitt wird erläutert, wie Sie die Beispiel-App konfigurieren.
Hinweis
Für Microsoft Entra ID und Azure AD B2C können Sie AddMicrosoftIdentityWebApp aus Microsoft Identity Web (NuGet-Paket Microsoft.Identity.Web
, API-Dokumentation) verwenden. Damit werden der OIDC- und der Cookie-Authentifizierungshandler mit den entsprechenden Standardwerten hinzugefügt. Die Beispiel-App und die Anleitung in diesem Abschnitt verwenden nicht Microsoft Identity Web. 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 in den verknüpften Ressourcen.
Die folgende OpenIdConnectOptions-Konfiguration befindet sich in der Datei Program
des Projekts beim Aufruf von AddOpenIdConnect:
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
undprofile
(Scope) (Optional): Die Bereicheopenid
undprofile
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 derAuthentication: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): Der Bereich
Weather.Get
wird im Azure- oder Entra-Portal unter Eine API verfügbar machen konfiguriert. Dies ist erforderlich, damit das Back-End-Web-API-Projekt (MinimalApiJwt
) das Zugriffstoken mit Bearer-JWT überprüft.oidcOptions.Scope.Add("{APP ID URI}/{API NAME}");
Beispiel:
- App-ID-URI (
{APP ID URI}
):https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
- Verzeichnisname (
{DIRECTORY NAME}
):contoso
- Anwendungs-ID (Client-ID) (
{CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
- Verzeichnisname (
- Bereich konfiguriert für Wetterdaten aus
MinimalApiJwt
({API NAME}
):Weather.Get
oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f/Weather.Get");
Das obige Beispiel bezieht sich auf eine App, die in einem Mandanten mit einem AAD B2C-Mandantentyp registriert ist. Wenn die App in einem ME-ID-Mandanten registriert wurde, ist der App-ID-URI und damit der Bereich ein anderer.
Beispiel:
- App-ID-URI (
{APP ID URI}
):api://{CLIENT ID}
mit Anwendungs-ID (Client-ID) ({CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
- Bereich konfiguriert für Wetterdaten aus
MinimalApiJwt
({API NAME}
):Weather.Get
oidcOptions.Scope.Add("api://4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f/Weather.Get");
- App-ID-URI (
Authority und ClientId: Legt die Autoritäts- und Client-ID für OIDC-Aufrufe fest.
oidcOptions.Authority = "{AUTHORITY}"; oidcOptions.ClientId = "{CLIENT ID}";
Beispiel:
- Autorität (
{AUTHORITY}
):https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/
(verwendet Mandanten-IDa3942615-d115-4eb7-bc84-9974abcf5064
) - Client-ID (
{CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/"; oidcOptions.ClientId = "4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
Beispiel für die Autorität „common“ von Microsoft Azure:
Die Autorität „common“ sollte für mehrinstanzenfähige Apps 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/";
- Autorität (
ClientSecret: Der geheimer OIDC-Clientschlüssel
Das folgende Beispiel dient nur zu Test- und Demonstrationszwecken. Speichern Sie den geheimen Clientschlüssel nicht in der Assembly der App, und checken Sie den geheimen Schlüssel nicht in die Quellcodeverwaltung ein. Speichern Sie den geheimen Clientschlüssel unter Benutzergeheimnisse, in Azure Key Vault oder in einer Umgebungsvariablen.
Die Authentifizierungsschemakonfiguration wird automatisch aus
builder.Configuration["Authentication:Schemes:{SCHEME NAME}:{PropertyName}"]
gelesen. Dabei ist der Platzhalter{SCHEME NAME}
das Schema (standardmäßigMicrosoftOidc
). Da die Konfiguration vorkonfiguriert ist, kann ein geheimer Clientschlüssel automatisch über den KonfigurationsschlüsselAuthentication:Schemes:MicrosoftOidc:ClientSecret
gelesen werden. Benennen Sie auf dem Server mithilfe von Umgebungsvariablen die UmgebungsvariableAuthentication__Schemes__MicrosoftOidc__ClientSecret
:set Authentication__Schemes__MicrosoftOidc__ClientSecret={CLIENT SECRET}
Nur zu Demonstrations- und Testzwecken. ClientSecret kann direkt festgelegt werden. Legen Sie den Wert nicht direkt für bereitgestellte Produktions-Apps fest. Für etwas mehr Sicherheit müssen Sie die Zeile bedingt mit dem Symbol
DEBUG
kompilieren:#if DEBUG oidcOptions.ClientSecret = "{CLIENT SECRET}"; #endif
Beispiel:
Geheimer Clientschlüssel (
{CLIENT SECRET}
):463471c8c4...f90d674bc9
(für die Darstellung gekürzt)#if DEBUG oidcOptions.ClientSecret = "463471c8c4...137f90d674bc9"; #endif
ResponseType: Konfiguriert den OIDC-Handler so, dass nur der Autorisierungscodeflow ausgeführt wird. Implizite Genehmigungen und Hybridflows sind in diesem Modus nicht erforderlich.
Aktivieren Sie in der App-Registrierungskonfiguration Implizite Genehmigung und Hybridflows im Entra- oder Azure-Portal *keins der Kontrollkästchen für den Autorisierungsendpunkt, um Zugriffstoken oder ID-Token zurückzugeben. 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
undrole
anstelle der Standardwerte für SOAP/WS-Fed in ClaimTypes. Wenn MapInboundClaims auffalse
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 aufroles
festgelegt, wie für die Microsoft Entra-ID (ME-ID) passend. Weitere Informationen dazu können Sie der Identitätsanbieter-Dokumentation entnehmen.
Hinweis
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 = JwtRegisteredClaimNames.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 (Anmelderückrufpfad) und für die Umleitung nach der Abmeldung (abgemeldeter 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
Legen Sie im Entra- oder Azure-Portal den Pfad im Umleitungs-URI der Plattformkonfiguration für Web fest:
https://localhost/signin-oidc
Hinweis
Für
localhost
-Adressen ist kein Port erforderlich.SignedOutCallbackPath: Der Anforderungspfad innerhalb des Basispfads der App, in dem der Benutzer-Agent nach der Abmeldung vom Identitätsanbieter zurückgegeben wird
Legen Sie im Entra- oder Azure-Portal den Pfad im Umleitungs-URI der Plattformkonfiguration für Web fest:
https://localhost/signout-callback-oidc
Hinweis
Für
localhost
-Adressen ist kein Port erforderlich.Hinweis
Bei Verwendung von Microsoft Identity Web leitet der Anbieter derzeit nur zurück an SignedOutCallbackPath um, wenn
microsoftonline.com
die Autorität (https://login.microsoftonline.com/{TENANT ID}/v2.0/
) verwendet wird. Diese Einschränkung besteht nicht, wenn Sie die Autorität „common“ mit Microsoft Identity Web verwenden können. Weitere Informationen finden Sie unter postLogoutRedirectUri funktioniert nicht, wenn die Autoritäts-URL eine Mandanten-ID enthält (AzureAD/microsoft-authentication-library-for-js
#5783).RemoteSignOutPath: Unter diesem Pfad empfangene Anforderungen führen dazu, dass der Handler die Abmeldung mithilfe des Abmeldeschemas aufruft.
Legen Sie im Entra- oder Azure-Portal die URL für Front-Channel-Abmeldung fest:
https://localhost/signout-oidc
Hinweis
Für
localhost
-Adressen ist kein Port erforderlich.
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-Validierungssteuerelement, wir müssen jedoch den Aussteller berücksichtigen, der mit der von
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
zurückgegebenen Mandanten-ID ({TENANT ID}
) 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;
Code der Beispiel-App
Sehen Sie sich die folgenden Features der Beispiel-App an:
- Automatische, nicht interaktive Tokenaktualisierung mithilfe einer benutzerdefinierten cookie-Aktualisierung (
CookieOidcRefresher.cs
) - 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. - Anforderungen an die Blazor-Web-App werden per Proxy an das Back-End-Web-API-Projekt (
MinimalApiJwt
) weitergeleitet.MapForwarder
in der DateiProgram
fügt eine direkte Weiterleitung von HTTP-Anforderungen, die dem angegebenen Muster entsprechen, an ein bestimmtes Ziel hinzu. Dabei werden die Standardkonfiguration für die ausgehende Anfrage, angepasste Transformationen und der Standard-HTTP-Client verwendet.- Beim Rendern der
Weather
Komponente auf dem Server verwendet die Komponente dieServerWeatherForecaster
Proxyanforderung für Wetterdaten mit dem Zugriffstoken des Benutzers. - Wenn die Komponente auf dem Client gerendert wird, verwendet die Komponente die
ClientWeatherForecaster
Dienstimplementierung, 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 ServerprojektsProgram
definiert ist, transformiert die Anforderung mit dem Zugriffstoken des Benutzers, um die Wetterdaten abzurufen.
- Beim Rendern der
Weitere Informationen zu (Web)-API-Aufrufen mithilfe einer Dienstabstraktion in Blazor Web Apps finden Sie unter Aufrufen einer Web-API aus einer ASP.NET Core-App Blazor.
Clientseitiges Blazor-Web-App-Projekt (BlazorWebAppOidc.Client
)
Das BlazorWebAppOidc.Client
-Projekt ist das clientseitige Projekt der Blazor-Web-App.
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. Es sind keine Token enthalten, die sich beim Senden von nachfolgenden Anforderungen beim Server authentifizieren und separat mithilfe eines cookie-Elements aus den HttpClient-Anforderungen an den Server verarbeitet werden.
Back-End-Web-API-Projekt (MinimalApiJwt
)
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. Anforderungen vom serverseitigen Projekt der Blazor-Web-App (BlazorWebAppOidc
) werden per Proxy an das Projekt MinimalApiJwt
weitergeleitet.
Konfiguration
Konfigurieren Sie das Projekt in JwtBearerOptions des AddJwtBearer-Aufrufs in der Datei Program
des Projekts:
Audience: Legt die Zielgruppe für alle empfangenen OpenID Connect-Token fest.
Im Azure- oder Entra-Portal: Passen Sie den Wert nur an den Pfad des Anwendungs-ID-URI an, der beim Hinzufügen des Bereichs
Weather.Get
unter Eine API verfügbar machen konfiguriert wird:jwtOptions.Audience = "{APP ID URI}";
Beispiel:
App-ID-URI (
{APP ID URI}
):https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
:- Verzeichnisname (
{DIRECTORY NAME}
):contoso
- Anwendungs-ID (Client-ID) (
{CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
jwtOptions.Audience = "https://contoso.onmicrosoft.com/4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
Das obige Beispiel bezieht sich auf eine App, die in einem Mandanten mit einem AAD B2C-Mandantentyp registriert ist. Wenn die App in einem ME-ID-Mandanten registriert wurde, ist der App-ID-URI und damit die Zielgruppe anders.
Beispiel:
App-ID-URI (
{APP ID URI}
):api://{CLIENT ID}
mit Anwendungs-ID (Client-ID) ({CLIENT ID}
):4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
jwtOptions.Audience = "api://4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
- Verzeichnisname (
Authority: Legt die Autorität für OpenID Connect-Aufrufe fest. Stimmen Sie den Wert auf die für den OIDC-Handler konfigurierte Autorität in
BlazorWebAppOidc/Program.cs
ab:jwtOptions.Authority = "{AUTHORITY}";
Beispiel:
Autorität (
{AUTHORITY}
):https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/
(verwendet Mandanten-IDa3942615-d115-4eb7-bc84-9974abcf5064
)jwtOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
Das obige Beispiel bezieht sich auf eine App, die in einem Mandanten mit einem AAD B2C-Mandantentyp registriert ist. Wenn die App in einem ME-ID-Mandanten registriert wurde, sollte die Autorität dem Aussteller (
iss
) in dem vom Identitätsanbieter zurückgegebenen JWT entsprechen:jwtOptions.Authority = "https://sts.windows.net/a3942615-d115-4eb7-bc84-9974abcf5064/";
Minimal-API für Wetterdaten
Sicherer Wettervorhersagedaten-Endpunkt in der Datei Program
des 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.
Hinzufügen von Komponenten, die interaktives serverseitiges Rendering übernehmen
Da die App das globale interaktive Autorendering über die Routes
Komponente verwendet, werden einzelne Komponenten, die interaktives serverseitiges Rendering (interaktives SSR, @rendermode InteractiveServer
) in ihrer Komponentendefinitionsdatei (.razor
) angeben, im Ordner des .Client
ProjektsPages
platziert.
Das Platzieren interaktiver SSR-Komponenten im .Client
Projekt ist kontraintuitiv, da diese Komponenten nur auf dem Server gerendert werden.
Wenn Sie eine interaktive SSR-Komponente im Components/Pages
Ordner des Serverprojekts platzieren, wird die Komponente normal und kurz im Browser des Benutzers angezeigt. Der clientseitige Router ist jedoch nicht in der Lage, die Komponente zu finden, was letztendlich zum Fehler 404 - Nicht gefunden führt.
Platzieren Sie daher interaktive SSR-Komponenten im Pages
Ordner des .Client
Projekts.
Umleitung auf die Willkommensseite beim Abmelden
Wenn Benutzer durch die App navigieren, legt die LogInOrOut
-Komponente (Layout/LogInOrOut.razor
) ein ausgeblendetes Feld für die Rückgabe-URL (ReturnUrl
) auf den Wert der aktuellen URL (currentURL
) fest. Wenn sich Benutzer bei der App abmelden, bringt der Identitätsanbieter sie auf die Seite zurück, von der sie sich abgemeldet haben.
Wenn sich Benutzer von einer sicheren Seite abmelden, gelangen sie nach dem Abmelden zur gleichen sicheren Seite und von dort aus zurück zum Authentifizierungsprozess. Dieses Verhalten ist in Ordnung, wenn Benutzer häufig die Konten wechseln müssen. Eine alternative App-Spezifikation kann jedoch erfordern, dass Benutzer nach der Abmeldung zur Willkommensseite der App oder zu einer anderen Seite gelangen. Das folgende Beispiel zeigt, wie die Startseite der App als Rückgabe-URL für Anmeldevorgänge festgelegt wird.
Die wichtigen Änderungen an der LogInOrOut
-Komponente werden im folgenden Beispiel veranschaulicht. Der value
des ausgeblendeten Felds für ReturnUrl
wird auf die Willkommensseite unter /
festgelegt. IDisposable wird nicht mehr implementiert. NavigationManager wird nicht mehr eingefügt. Der gesamte @code
-Block wird entfernt.
Layout/LogInOrOut.razor
:
@using Microsoft.AspNetCore.Authorization
<div class="nav-item px-3">
<AuthorizeView>
<Authorized>
<form action="authentication/logout" method="post">
<AntiforgeryToken />
<input type="hidden" name="ReturnUrl" value="/" />
<button type="submit" class="nav-link">
<span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true">
</span> Logout @context.User.Identity?.Name
</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>
Kryptografische Nonce
Eine Nonce ist ein Zeichenfolgenwert, der der Sitzung eines Clients einem ID-Token zuordnet, um Replay-Angriffe zu minimieren.
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 in den Abschnitten Cookie und "Websitedaten ".
Eine Nonce ist nicht erforderlich oder wird nicht verwendet, wenn ein Aktualisierungstoken für ein neues Zugriffstoken ausgetauscht wird. In der Beispiel-App wird OpenIdConnectProtocolValidator.RequireNonce durch dieCookieOidcRefresher
( CookieOidcRefresher.cs
) absichtlich auf false
gesetzt.
Anwendungsrollen für Apps, die nicht bei Microsoft Entra registriert sind (ME-ID)
Dieser Abschnitt bezieht sich auf Apps, die die Microsoft Entra ID (ME-ID) nicht 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 den Rollenanspruchstyp (TokenValidationParameters.RoleClaimType) in OpenIdConnectOptions von Program.cs
:
oidcOptions.TokenValidationParameters.RoleClaimType = "{ROLE CLAIM TYPE}";
Bei vielen OIDC-Identitätsanbietern lautet 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 werden in role
-Ansprüchen angezeigt – ein Anspruch 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.
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 Rollenanspruch konfigurieren (ME-ID-Dokumentation).
Die Azure-Sicherheitsgruppen von Benutzenden kommen in groups
-Ansprüchen an, und die integrierten Rollenzuweisungen für ME-ID-Admins von Benutzenden kommen in bekannten IDs (wids
-Ansprüche) an. Werte für beide Anspruchstypen sind GUIDs. Wenn sie von der App empfangen werden, können diese Ansprüche 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
All
fest ("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 werden in
roles
-Ansprüchen angezeigt – ein Anspruch pro Rolle. - Sicherheitsgruppen werden in
groups
-Ansprüchen angezeigt – ein Anspruch pro Gruppe. Die Sicherheitsgruppen-GUIDs werden im Azure-Portal angezeigt, wenn Sie eine Sicherheitsgruppe erstellen und wenn Sie beim Auswählen von Identity>Übersicht>Gruppen>Ansicht aufgeführt werden. - Integrierte ME-ID-Adminrollen werden in
wids
-Ansprüchen angezeigt – ein Anspruch pro Rolle. Derwids
-Anspruch mit einem Wert vonb79fbf4d-3ef9-4689-8143-76b194e85509
wird 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 Rollenvorlagen-IDs werden auch in integrierten Microsoft Entra-Rollen (Entra-Dokumentation) aufgeführt.
Problembehandlung
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.
Informationen zum Aktivieren der Debug- oder Ablaufverfolgungsprotokollierung für die Blazor WebAssembly-Authentifizierung finden Sie im Abschnitt zur clientseitigen Authentifizierungsprotokollierung ASP.NET Core-Blazor-Protokollierung, wobei die Artikelversionsauswahl auf ASP.NET Core 7.0 oder höher festgelegt ist.
Häufige Fehler
Falsche Konfiguration der App oder des Identity-Anbieters (Identity Provider, 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, die nach App- und IP-Fehlkonfigurationen sucht.
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 wird vom IP oder von der Server-App eine präzise Fehlermeldung oder eine Meldung mit einem Hinweis auf die Ursache des Problems zurückgegeben, nachdem eine Anforderung erfolgt ist. 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 Angreifern ausgenutzt werden könnte, lesen Sie bitte den Abschnitt Melden von Sicherheitsproblemen und Fehlern (
dotnet/aspnetcore
GitHub 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 aufnull
odertrue
fest.
- 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:
- cookies für Benutzeranmeldung
- cookies für App
- 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 mithilfe der Schaltfläche Ausführen von Visual Studio das Dialogfeld Browserauswahl.
- 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 Anzeigename 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 funktionsfähige App kann direkt nach der Durchführung eines Upgrades für das .NET Core SDK auf dem Entwicklungscomputer oder einer Änderung der Paketversionen in 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 --clear
in einer Befehlsshell ausführen. - Löschen Sie die Ordner
bin
undobj
des 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.
Hinweis
Die Verwendung von Paketversionen, die mit dem Zielframework der App nicht kompatibel sind, wird nicht unterstützt. Informationen zu einem Paket finden Sie mithilfe der NuGet Gallery oder des FuGet Package Explorer.
Ausführen der Server-App
Stellen Sie beim Testen und Beheben von Problemen bei einer gehosteten Blazor-App sicher, dass Sie die Blazor-Web-App aus dem Serverprojekt ausführen.
Ü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;
}
}
Zusätzliche Ressourcen
AzureAD/microsoft-identity-web
GitHub-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 nicht explizit in der Azure-Dokumentation behandelt, aber die Einrichtung und Konfiguration einer Blazor-Web-App für ME-ID und Azure-Hosting entsprechen der Einrichtung und Konfiguration einer beliebigen ASP.NET Core-Web-App.AuthenticationStateProvider
Dienst- Verwalten des Authentifizierungsstatus in Blazor-Web-Apps
- Aktualisierungstoken während der HTTP-Anforderung in Blazor Interactive Server mit OIDC (
dotnet/aspnetcore
#55213)