Sdílet prostřednictvím


Zabezpečení ASP.NET Core Blazor Web App pomocí OpenID Connect (OIDC)

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Tento článek popisuje, jak zabezpečit openID Blazor Web App pomocí ukázkové aplikace vdotnet/blazor-samples (jak stáhnout).

Tato verze článku popisuje implementaci OIDC bez přijetí modelu back-endu pro front-end (BFF). Model BFF je užitečný pro provádění ověřených požadavků na externí služby. Pokud specifikace aplikace volá přijetí vzoru BFF, změňte selektor verze článku na OIDC s modelem BFF .

Probírá se následující specifikace:

  • Používá Blazor Web Apprežim automatického vykreslování s globální interaktivitou.
  • Vlastní služby zprostředkovatele stavu ověřování používají serverové a klientské aplikace k zachycení stavu ověřování uživatele a jeho toku mezi serverem a klientem.
  • Tato aplikace je výchozím bodem pro jakýkoli tok ověřování OIDC. OIDC je v aplikaci nakonfigurovaný ručně a nespoléhá na microsoft Entra ID ani Identity balíčky Microsoftu, ani ukázková aplikace nevyžaduje hostování Microsoft Azure. Ukázkovou aplikaci ale můžete použít s entra, webem Microsoftu Identity a hostovanými v Azure.
  • Automatická neinteraktivní aktualizace tokenu
  • Bezpečně volá (webové) rozhraní API v serverovém projektu pro data.

Alternativní možnosti použití Microsoft Authentication Library pro .NET, Microsoft Identity Weba Microsoft Entra ID, viz Zabezpečení ASP.NET Core Blazor Web App pomocíMicrosoft Entra ID .

Ukázková aplikace

Ukázková aplikace se skládá ze dvou projektů:

  • BlazorWebAppOidc: Projekt Blazor Web Appna straně serveru , který obsahuje příklad minimálního koncového bodu rozhraní API pro data o počasí.
  • BlazorWebAppOidc.Client: Projekt na straně klienta .Blazor Web App

Pomocí následujícího odkazu přejděte k ukázkovým aplikacím prostřednictvím složky nejnovější verze z kořenového adresáře úložiště. Projekty jsou ve BlazorWebAppOidc složce pro .NET 8 nebo novější.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Projekt na straně Blazor Web App serveru (BlazorWebAppOidc)

Projekt BlazorWebAppOidc je projekt Blazor Web Appna straně serveru .

Soubor BlazorWebAppOidc.http lze použít k testování žádosti o data o počasí. Mějte na paměti, že projekt BlazorWebAppOidc musí být spuštěn pro otestování koncového bodu a koncový bod je pevně zakódovaný do souboru. Další informace naleznete v tématu Použití souborů .http v sadě Visual Studio 2022.

Konfigurace

Tato část vysvětluje, jak nakonfigurovat ukázkovou aplikaci.

Poznámka:

Pro Microsoft Entra ID nebo Azure AD B2C můžete použít z webu Microsoftu AddMicrosoftIdentityWebApp (Identitybalíček NuGet, Microsoft.Identity.Web k rozhraní API), který přidává obslužné rutiny OIDC i ověřování s příslušnými výchozími nastaveními.Cookie Ukázková aplikace a pokyny v této části nepoužívají web Microsoftu Identity . Pokyny ukazují, jak RUČNĚ nakonfigurovat obslužnou rutinu OIDC pro libovolného zprostředkovatele OIDC. Další informace o implementaci webu společnosti Microsoft Identity naleznete v odkazovaných prostředcích.

Vytvoření tajného klíče klienta

Upozorňující

Neukládejte tajné kódy aplikací, připojovací řetězec, přihlašovací údaje, hesla, osobní identifikační čísla (PIN), privátní kód C#/.NET nebo privátní klíče/tokeny v kódu na straně klienta, což je vždy nezabezpečené. V testovacích a pracovních a produkčních prostředích by kód na straně Blazor serveru a webová rozhraní API měly používat toky zabezpečeného ověřování, které se vyhýbají údržbě přihlašovacích údajů v kódu projektu nebo konfiguračních souborech. Mimo místní testování vývoje doporučujeme vyhnout se použití proměnných prostředí k ukládání citlivých dat, protože proměnné prostředí nejsou nejbezpečnějším přístupem. Pro místní testování vývoje se pro zabezpečení citlivých dat doporučuje nástroj Secret Manager. Další informace najdete v tématu Bezpečné udržování citlivých dat a přihlašovacích údajů.

K místnímu testování vývoje použijte nástroj Secret Manager k uložení tajného klíče klienta serverové aplikace pod konfiguračním klíčem Authentication:Schemes:MicrosoftOidc:ClientSecret.

Poznámka:

Pokud aplikace používá Microsoft Entra ID nebo Azure AD B2C, vytvořte tajný klíč klienta v registraci aplikace na webu Entra nebo Azure Portal (>Nového tajného klíče klienta). Hodnotu nového tajného kódu použijte v následujících doprovodných materiálech.

Ukázková aplikace nebyla inicializována pro nástroj Secret Manager. K provedení následujícího příkazu použijte příkazové prostředí, například příkazové prostředí Developer PowerShell v sadě Visual Studio. Před provedením příkazu změňte adresář příkazem cd na adresář projektu serveru. Příkaz vytvoří identifikátor tajných kódů uživatele (<UserSecretsId> v souboru projektu serverové aplikace):

dotnet user-secrets init

Spuštěním následujícího příkazu nastavte tajný klíč klienta. Zástupný {SECRET} symbol je tajný klíč klienta získaný z registrace aplikace:

dotnet user-secrets set "Authentication:Schemes:MicrosoftOidc:ClientSecret" "{SECRET}"

Pokud používáte Visual Studio, můžete ověřit, že je tajný kód nastavený tak, že v Průzkumník řešení kliknete pravým tlačítkem na projekt serveru a vyberete Spravovat tajné kódy uživatelů.

Konfigurace aplikace

Následující OpenIdConnectOptions konfigurace se nachází v souboru projektu Program při volání AddOpenIdConnect:

  • SignInScheme: Nastaví schéma ověřování odpovídající middlewaru zodpovědnému za zachování uživatele identity po úspěšném ověření. Obslužná rutina OIDC musí používat schéma přihlašování, které dokáže uchovávat přihlašovací údaje uživatelů napříč požadavky. Následující řádek je k dispozici pouze pro demonstrační účely. Pokud tuto hodnotu vynecháte, DefaultSignInScheme použije se jako záložní hodnota.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Obory pro openid a profile () (Scopevolitelné): Obory openid a profile obory jsou také ve výchozím nastavení nakonfigurované, protože jsou vyžadovány pro fungování obslužné rutiny OIDC, ale pokud jsou obory zahrnuté v Authentication:Schemes:MicrosoftOidc:Scope konfiguraci, může být potřeba je znovu přidat. Obecné pokyny ke konfiguraci najdete v tématu Konfigurace v konfiguraci ASP.NET Core a ASP.NET CoreBlazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: Definuje, jestli mají být po úspěšné autorizaci uloženy AuthenticationProperties přístupové a obnovovací tokeny. Tato vlastnost je nastavena tak, aby false se zmenšila velikost konečného ověřování cookie.

    oidcOptions.SaveTokens = false;
    
  • Rozsah pro offline přístup (Scope): Obor offline_access je vyžadován pro obnovovací token.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Authority a ClientId: Nastaví autoritu a ID klienta pro volání OIDC.

    oidcOptions.Authority = "{AUTHORITY}";
    oidcOptions.ClientId = "{CLIENT ID}";
    

    Příklad:

    • Autorita (): {AUTHORITY} (https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/používá ID aaaabbbb-0000-cccc-1111-dddd2222eeeetenanta)
    • ID klienta ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
    oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
    

    Příklad pro "běžnou" autoritu Microsoft Azure:

    Pro aplikace s více tenanty by se měla používat "společná" autorita. Můžete také použít "společnou" autoritu pro aplikace s jedním tenantem, ale vyžaduje se vlastní IssuerValidator , jak je znázorněno dále v této části.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ResponseType: Nakonfiguruje obslužnou rutinu OIDC tak, aby prováděla pouze tok autorizačního kódu. Implicitní granty a hybridní toky nejsou v tomto režimu zbytečné. Obslužná rutina OIDC automaticky požaduje příslušné tokeny pomocí kódu vráceného z autorizačního koncového bodu.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    

    Poznámka:

    V konfiguraci implicitního udělení a hybridních toků aplikace entra nebo webu Azure Portal nevybírejte políčko pro koncový bod autorizace pro vrácení přístupových tokenů nebo tokenů ID.

  • MapInboundClaimsa konfigurace NameClaimType a : Mnoho serverů OIDC používá "RoleClaimType" a "name" místo výchozích hodnot SOAP/WS-Fed v roleClaimTypes. Pokud MapInboundClaims je nastavená hodnota false, obslužná rutina neprovádí mapování deklarací identity a názvy deklarací identity z JWT používají přímo aplikace. Následující příklad nastaví typ deklarace identity role na "roles, což je vhodné pro Microsoft Entra ID (ME-ID). Další informace najdete v dokumentaci poskytovatele identity .

    Poznámka:

    MapInboundClaims musí být nastavena na false většinu zprostředkovatelů OIDC, což brání přejmenování deklarací identity.

    oidcOptions.MapInboundClaims = false;
    oidcOptions.TokenValidationParameters.NameClaimType = "name";
    oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
    
  • Konfigurace cesty: Cesty musí odpovídat identifikátoru URI přesměrování (cesta zpětného volání přihlášení) a cestě k přesměrování odhlášení (cesta zpětného volání odhlášení) nakonfigurované při registraci aplikace u poskytovatele OIDC. Na webu Azure Portal se cesty konfigurují v okně Ověřování registrace aplikace. Přihlašovací i odhlašující cesty musí být zaregistrované jako identifikátory URI přesměrování. Výchozí hodnoty jsou /signin-oidc a /signout-callback-oidc.

    • CallbackPath: Cesta požadavku v rámci základní cesty aplikace, kde se vrátí uživatelský agent.

      Nakonfigurujte v registraci zprostředkovatele OIDC aplikace cestu zpětného volání pro odhlášení. V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

      https://localhost:{PORT}/signin-oidc

      Poznámka:

      Pro adresy při použití ID Microsoft Entra se port nevyžaduje localhost . Většina ostatních zprostředkovatelů OIDC vyžaduje správný port.

    • SignedOutCallbackPath (konfigurační klíč: "SignedOutCallbackPath"): Cesta požadavku v rámci základní cesty aplikace zachycená obslužnou rutinou OIDC, kde se agent uživatele poprvé vrátí po odhlášení od poskytovatele identity. Ukázková aplikace nenastaví pro cestu hodnotu, protože se použije výchozí hodnota/signout-callback-oidc. Po zachycení požadavku se obslužná rutina OIDC přesměruje na SignedOutRedirectUri nebo RedirectUri, pokud je to specifikováno.

      Nakonfigurujte cestu zpětného volání odhlášení v registraci zprostředkovatele OIDC aplikace. V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

      https://localhost:{PORT}/signout-callback-oidc

      Poznámka:

      Pokud používáte ID Microsoft Entra, nastavte cestu v konfiguraci platformy Web v položkách identifikátoru URI přesměrování v portálu Entra nebo Azure. Port se při použití Entra nevyžaduje pro adresy localhost. Většina ostatních zprostředkovatelů OIDC vyžaduje správný port. Pokud do registrace aplikace v Entra nepřidáte identifikátor URI cesty zpětného volání po odhlášení, Entra nepřesměruje uživatele zpět do aplikace a pouze je vyzve, aby zavřeli okno prohlížeče.

    • RemoteSignOutPath: Požadavky přijaté na této cestě způsobí, že obslužná rutina vyvolá odhlášení pomocí schématu odhlášení.

      V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

      https://localhost/signout-oidc

      Poznámka:

      Pokud používáte ID Microsoft Entra, nastavte adresu URL pro odhlášení front-channel v portálu Entra nebo Azure. Při použití Entra se port nevyžaduje pro adresy localhost. Většina ostatních zprostředkovatelů OIDC vyžaduje správný port.

      oidcOptions.CallbackPath = new PathString("{PATH}");
      oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
      oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
      

      Příklady (výchozí hodnoty):

      oidcOptions.CallbackPath = new PathString("/signin-oidc");
      oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
      oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
      
  • (Microsoft Azure pouze s běžným koncovým bodem): TokenValidationParameters.IssuerValidatorMnoho zprostředkovatelů OIDC pracuje s výchozím validátorem vystavitele, ale musíme počítat s parametrizovaným vystavitelem s ID tenanta ({TENANT ID}) vráceným https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. Další informace najdete v tématu SecurityTokenInvalidIssuerException s OpenID Connect a koncovým bodem Azure AD "common" (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Pouze pro aplikace používající Microsoft Entra ID nebo Azure AD B2C s "běžným" koncovým bodem:

    var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
    oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
    

Ukázkový kód aplikace

Zkontrolujte ukázkovou aplikaci a zkontrolujte následující funkce:

  • Automatická neinteraktivní aktualizace tokenů pomocí vlastního cookie aktualizačního modulu (CookieOidcRefresher.cs).
  • Volání projektu AddAuthenticationStateSerialization serveru pro přidání zprostředkovatele stavu ověřování na straně serveru, který používá PersistentComponentState k toku stav ověřování do klienta. Klient volá AddAuthenticationStateDeserialization deserializaci a používá stav ověřování předaný serverem. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.
  • Příkladem požadavků na Blazor Web App data o počasí je v souboru () minimální koncový bod rozhraní API (/weather-forecastProgram).Program.cs Koncový bod vyžaduje autorizaci voláním RequireAuthorization. Pro všechny kontrolery, které přidáte do projektu, přidejte [Authorize] atribut do kontroleru nebo akce.
  • Aplikace bezpečně volá (webové) rozhraní API v serverovém projektu pro data o počasí:
    • Při vykreslování Weather komponenty na serveru komponenta používá komponentu ServerWeatherForecaster na serveru k přímému získání dat o počasí (ne prostřednictvím volání webového rozhraní API).
    • Při vykreslení komponenty v klientovi používá ClientWeatherForecaster komponenta implementaci služby, která používá předkonfigurované HttpClient (v souboru klientského Program projektu) k volání webového rozhraní API do projektu serveru. Minimální koncový bod rozhraní API (/weather-forecast) definovaný v souboru projektu Program serveru získá data o počasí z ServerWeatherForecaster klienta a vrátí data klientovi.
  • Automatická neinteraktivní aktualizace tokenů pomocí vlastního cookie aktualizačního modulu (CookieOidcRefresher.cs).
  • PersistingAuthenticationStateProvider Třída (PersistingAuthenticationStateProvider.cs) je serverová stranaAuthenticationStateProvider, která používá PersistentComponentState k toku stav ověřování do klienta, což je opraveno po dobu životnosti aplikace WebAssembly.
  • Příkladem požadavků na Blazor Web App data o počasí je v souboru () minimální koncový bod rozhraní API (/weather-forecastProgram).Program.cs Koncový bod vyžaduje autorizaci voláním RequireAuthorization. Pro všechny kontrolery, které přidáte do projektu, přidejte [Authorize] atribut do kontroleru nebo akce.
  • Aplikace bezpečně volá (webové) rozhraní API v serverovém projektu pro data o počasí:
    • Při vykreslování Weather komponenty na serveru komponenta používá komponentu ServerWeatherForecaster na serveru k přímému získání dat o počasí (ne prostřednictvím volání webového rozhraní API).
    • Při vykreslení komponenty v klientovi používá ClientWeatherForecaster komponenta implementaci služby, která používá předkonfigurované HttpClient (v souboru klientského Program projektu) k volání webového rozhraní API do projektu serveru. Minimální koncový bod rozhraní API (/weather-forecast) definovaný v souboru projektu Program serveru získá data o počasí z ServerWeatherForecaster klienta a vrátí data klientovi.

Další informace o (webových) voláních rozhraní API pomocí abstrakcí služby v Blazor Web Apps najdete v tématu Blazor ASP.NET Core.

Projekt na straně Blazor Web App klienta (BlazorWebAppOidc.Client)

Projekt BlazorWebAppOidc.Client je projekt Blazor Web Appna straně klienta .

Klient volá AddAuthenticationStateDeserialization deserializaci a používá stav ověřování předaný serverem. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.

PersistentAuthenticationStateProvider Třída (PersistentAuthenticationStateProvider.cs) je na straně AuthenticationStateProvider klienta, která určuje stav ověřování uživatele vyhledáním dat uložených na stránce, když byla vykreslena na serveru. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.

Pokud se uživatel potřebuje přihlásit nebo odhlásit, vyžaduje se opětovné načtení celé stránky.

Ukázková aplikace poskytuje jenom uživatelské jméno a e-mail pro účely zobrazení. Nezahrnuje tokeny, které se ověřují na serveru při provádění následných požadavků, které fungují samostatně s využitím cookie požadavků, které jsou součástí požadavků na HttpClient server.

Tato verze článku popisuje implementaci OIDC se vzorem back-endu pro front-end (BFF). Pokud specifikace aplikace nevyvolá přijetí vzoru BFF, změňte selektor verze článku na OIDC bez vzoru BFF.

Probírá se následující specifikace:

  • Používá Blazor Web Apprežim automatického vykreslování s globální interaktivitou.
  • Vlastní služby zprostředkovatele stavu ověřování používají serverové a klientské aplikace k zachycení stavu ověřování uživatele a jeho toku mezi serverem a klientem.
  • Tato aplikace je výchozím bodem pro jakýkoli tok ověřování OIDC. OIDC je v aplikaci nakonfigurovaný ručně a nespoléhá na microsoft Entra ID ani Identity balíčky Microsoftu, ani ukázková aplikace nevyžaduje hostování Microsoft Azure. Ukázkovou aplikaci ale můžete použít s entra, webem Microsoftu Identity a hostovanými v Azure.
  • Automatická neinteraktivní aktualizace tokenu
  • Model Back-endu pro front-end (BFF) se používá .NET Aspire pro zjišťování služeb a YARP pro proxy požadavky na koncový bod předpovědi počasí v back-endové aplikaci.
    • Back-endové webové rozhraní API používá ověřování nosný JWT k ověření tokenů JWT uložených Blazor Web App v přihlášení cookie.
    • Aspire zlepšuje prostředí vytváření aplikací nativních pro cloud .NET. Poskytuje konzistentní sadu nástrojů a vzorů pro vytváření a spouštění distribuovaných aplikací.
    • YARP (další reverzní proxy server) je knihovna, která slouží k vytvoření reverzního proxy serveru.

Další informace o .NET Aspireobecné dostupnosti: Zjednodušení vývoje nativního .NET Aspirepro cloud .NET (květen 2024)

Požadavek

.NET Aspire vyžaduje Visual Studio verze 17.10 nebo novější.

Ukázková aplikace

Ukázková aplikace se skládá z pěti projektů:

  • .NET Aspire:
    • Aspire.AppHost: Slouží ke správě aspektů orchestrace vysoké úrovně aplikace.
    • Aspire.ServiceDefaults: Obsahuje výchozí .NET Aspire konfigurace aplikací, které je možné podle potřeby rozšířit a přizpůsobit.
  • MinimalApiJwt: Back-endové webové rozhraní API, které obsahuje příklad koncového bodu rozhraní API pro data o počasí.
  • BlazorWebAppOidc: Projekt na straně serveru .Blazor Web App
  • BlazorWebAppOidc.Client: Projekt na straně klienta .Blazor Web App

Pomocí následujícího odkazu přejděte k ukázkovým aplikacím prostřednictvím složky nejnovější verze z kořenového adresáře úložiště. Projekty jsou ve BlazorWebAppOidcBff složce pro .NET 8 nebo novější.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

.NET Aspire projektů

Další informace o použití .NET Aspire a .AppHost podrobnostech o .ServiceDefaults projektech ukázkové aplikace najdete v .NET Aspire dokumentaci.

Ověřte, že jste splnili požadavky pro .NET Aspire. Další informace najdete v části Požadavky v rychlém startu : Sestavení první .NET Aspire aplikace.

Ukázková aplikace konfiguruje jenom nezabezpečený spouštěcí profil HTTP (http) pro použití při testování vývoje. Další informace, včetně příkladu nezabezpečených a zabezpečených profilů nastavení spuštění, naleznete v tématu Povolení nezabezpečeného přenosu v .NET Aspire (.NET Aspire dokumentace).

Projekt na straně Blazor Web App serveru (BlazorWebAppOidc)

Projekt BlazorWebAppOidc je projekt Blazor Web Appna straně serveru . Projekt používá YARP k proxy žádostem o koncový bod předpovědi počasí v projektu back-endového webového rozhraní API (MinimalApiJwt) s uloženým access_token v ověřování cookie.

Soubor BlazorWebAppOidc.http lze použít k testování žádosti o data o počasí. Mějte na paměti, že projekt BlazorWebAppOidc musí být spuštěn pro otestování koncového bodu a koncový bod je pevně zakódovaný do souboru. Další informace naleznete v tématu Použití souborů .http v sadě Visual Studio 2022.

Konfigurace

Tato část vysvětluje, jak nakonfigurovat ukázkovou aplikaci.

Poznámka:

Pro Microsoft Entra ID nebo Azure AD B2C můžete použít z webu Microsoftu AddMicrosoftIdentityWebApp (Identitybalíček NuGet, Microsoft.Identity.Web k rozhraní API), který přidává obslužné rutiny OIDC i ověřování s příslušnými výchozími nastaveními.Cookie Ukázková aplikace a pokyny v této části nepoužívají web Microsoftu Identity . Pokyny ukazují, jak RUČNĚ nakonfigurovat obslužnou rutinu OIDC pro libovolného zprostředkovatele OIDC. Další informace o implementaci webu společnosti Microsoft Identity naleznete v odkazovaných prostředcích.

Vytvoření tajného klíče klienta

Upozorňující

Neukládejte tajné kódy aplikací, připojovací řetězec, přihlašovací údaje, hesla, osobní identifikační čísla (PIN), privátní kód C#/.NET nebo privátní klíče/tokeny v kódu na straně klienta, což je vždy nezabezpečené. V testovacích a pracovních a produkčních prostředích by kód na straně Blazor serveru a webová rozhraní API měly používat toky zabezpečeného ověřování, které se vyhýbají údržbě přihlašovacích údajů v kódu projektu nebo konfiguračních souborech. Mimo místní testování vývoje doporučujeme vyhnout se použití proměnných prostředí k ukládání citlivých dat, protože proměnné prostředí nejsou nejbezpečnějším přístupem. Pro místní testování vývoje se pro zabezpečení citlivých dat doporučuje nástroj Secret Manager. Další informace najdete v tématu Bezpečné udržování citlivých dat a přihlašovacích údajů.

K místnímu testování vývoje použijte nástroj Secret Manager k uložení tajného klíče klienta serverové aplikace pod konfiguračním klíčem Authentication:Schemes:MicrosoftOidc:ClientSecret.

Poznámka:

Pokud aplikace používá Microsoft Entra ID nebo Azure AD B2C, vytvořte tajný klíč klienta v registraci aplikace na webu Entra nebo Azure Portal (>Nového tajného klíče klienta). Hodnotu nového tajného kódu použijte v následujících doprovodných materiálech.

Ukázková aplikace nebyla inicializována pro nástroj Secret Manager. K provedení následujícího příkazu použijte příkazové prostředí, například příkazové prostředí Developer PowerShell v sadě Visual Studio. Před provedením příkazu změňte adresář příkazem cd na adresář projektu serveru. Příkaz vytvoří identifikátor tajných kódů uživatele (<UserSecretsId> v souboru projektu serverové aplikace):

dotnet user-secrets init

Spuštěním následujícího příkazu nastavte tajný klíč klienta. Zástupný {SECRET} symbol je tajný klíč klienta získaný z registrace aplikace:

dotnet user-secrets set "Authentication:Schemes:MicrosoftOidc:ClientSecret" "{SECRET}"

Pokud používáte Visual Studio, můžete ověřit, že je tajný kód nastavený tak, že v Průzkumník řešení kliknete pravým tlačítkem na projekt serveru a vyberete Spravovat tajné kódy uživatelů.

Konfigurace aplikace

Následující OpenIdConnectOptions konfigurace se nachází v souboru projektu Program při volání AddOpenIdConnect:

  • SignInScheme: Nastaví schéma ověřování odpovídající middlewaru zodpovědnému za zachování uživatele identity po úspěšném ověření. Obslužná rutina OIDC musí používat schéma přihlašování, které dokáže uchovávat přihlašovací údaje uživatelů napříč požadavky. Následující řádek je k dispozici pouze pro demonstrační účely. Pokud tuto hodnotu vynecháte, DefaultSignInScheme použije se jako záložní hodnota.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Obory pro openid a profile () (Scopevolitelné): Obory openid a profile obory jsou také ve výchozím nastavení nakonfigurované, protože jsou vyžadovány pro fungování obslužné rutiny OIDC, ale pokud jsou obory zahrnuté v Authentication:Schemes:MicrosoftOidc:Scope konfiguraci, může být potřeba je znovu přidat. Obecné pokyny ke konfiguraci najdete v tématu Konfigurace v konfiguraci ASP.NET Core a ASP.NET CoreBlazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: Definuje, jestli mají být po úspěšné autorizaci uloženy AuthenticationProperties přístupové a obnovovací tokeny. Hodnota je nastavená na true ověření požadavků na data o počasí z projektu back-endového webového rozhraní API (MinimalApiJwt).

    oidcOptions.SaveTokens = true;
    
  • Rozsah pro offline přístup (Scope): Obor offline_access je vyžadován pro obnovovací token.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Rozsahy pro získání dat o počasí z webového rozhraní API (Scope): To je nezbytné pro projekt back-endového webového rozhraní API (MinimalApiJwt) k ověření přístupového tokenu s nosným JWT.

    oidcOptions.Scope.Add("{APP ID URI}/{API NAME}");
    

    Poznámka:

    Při použití ID Microsoft Entra se obor Weather.Get konfiguruje prostřednictvím portálů Azure nebo Entra v části Zpřístupnit rozhraní API.

    Příklad:

    • Identifikátor URI ID aplikace ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
      • Název adresáře ({DIRECTORY NAME}): contoso
      • ID{CLIENT ID} aplikace (klienta): 00001111-aaaa-2222-bbbb-3333cccc4444
    • Rozsah nakonfigurovaný pro data o počasí z MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/Weather.Get");
    

    Předchozí příklad se týká aplikace zaregistrované v tenantovi s typem tenanta AAD B2C. Pokud je aplikace zaregistrovaná v tenantovi ME-ID, identifikátor URI ID aplikace se liší, a proto se rozsah liší.

    Příklad:

    • Identifikátor URI ID aplikace ({APP ID URI}): api://{CLIENT ID} s ID aplikace (klient) ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    • Rozsah nakonfigurovaný pro data o počasí z MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("api://00001111-aaaa-2222-bbbb-3333cccc4444/Weather.Get");
    
  • Authority a ClientId: Nastaví autoritu a ID klienta pro volání OIDC.

    oidcOptions.Authority = "{AUTHORITY}";
    oidcOptions.ClientId = "{CLIENT ID}";
    

    Příklad:

    • Autorita (): {AUTHORITY} (https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/používá ID aaaabbbb-0000-cccc-1111-dddd2222eeeetenanta)
    • ID klienta ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
    oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
    

    Příklad pro "běžnou" autoritu Microsoft Azure:

    Pro aplikace s více tenanty by se měla používat "společná" autorita. Můžete také použít "společnou" autoritu pro aplikace s jedním tenantem, ale vyžaduje se vlastní IssuerValidator , jak je znázorněno dále v této části.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ResponseType: Nakonfiguruje obslužnou rutinu OIDC tak, aby prováděla pouze tok autorizačního kódu. Implicitní granty a hybridní toky nejsou v tomto režimu zbytečné. Obslužná rutina OIDC automaticky požaduje příslušné tokeny pomocí kódu vráceného z autorizačního koncového bodu.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    

    Poznámka:

    Při použití ID Microsoft Entra zaškrtněte políčko u koncového bodu autorizace, aby se vrátily přístupové tokeny nebo tokeny ID v implicitní udělení a hybridní toky konfiguraci registrace aplikace.

  • MapInboundClaimsa konfigurace NameClaimType a : Mnoho serverů OIDC používá "RoleClaimType" a "name" místo výchozích hodnot SOAP/WS-Fed v roleClaimTypes. Pokud MapInboundClaims je nastavená hodnota false, obslužná rutina neprovádí mapování deklarací identity a názvy deklarací identity z JWT používají přímo aplikace. Následující příklad nastaví typ deklarace identity role na "roles, což je vhodné pro Microsoft Entra ID (ME-ID). Další informace najdete v dokumentaci poskytovatele identity .

    Poznámka:

    MapInboundClaims musí být nastavena na false většinu zprostředkovatelů OIDC, což brání přejmenování deklarací identity.

    oidcOptions.MapInboundClaims = false;
    oidcOptions.TokenValidationParameters.NameClaimType = "name";
    oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
    
  • Konfigurace cesty: Cesty musí odpovídat identifikátoru URI přesměrování (cesta zpětného volání přihlášení) a cestě k přesměrování odhlášení (cesta zpětného volání odhlášení) nakonfigurované při registraci aplikace u poskytovatele OIDC. Na webu Azure Portal se cesty konfigurují v okně Ověřování registrace aplikace. Přihlašovací i odhlašující cesty musí být zaregistrované jako identifikátory URI přesměrování. Výchozí hodnoty jsou /signin-oidc a /signout-callback-oidc.

    Nakonfigurujte cestu pro zpětné volání při odhlášení v registraci poskytovatele OIDC aplikace. V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

    https://localhost:{PORT}/signin-oidc

    Poznámka:

    Pro adresy při použití ID Microsoft Entra se port nevyžaduje localhost . Většina ostatních zprostředkovatelů OIDC vyžaduje správný port.

    • SignedOutCallbackPath (konfigurační klíč: "SignedOutCallbackPath"): Cesta požadavku v rámci základní cesty aplikace zachycená obslužnou rutinou OIDC, kde se agent uživatele poprvé vrátí po odhlášení od poskytovatele identity. Ukázková aplikace nenastaví pro cestu hodnotu, protože se použije výchozí hodnota/signout-callback-oidc. Po zachycení požadavku se obslužná rutina OIDC přesměruje na SignedOutRedirectUri nebo RedirectUri, pokud je to uvedeno.

      Nakonfigurujte cestu zpětného volání po odhlášení v registraci poskytovatele OIDC pro aplikaci. V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

      https://localhost:{PORT}/signout-callback-oidc

      Poznámka:

      Pokud používáte ID Microsoft Entra, nastavte cestu v konfiguraci platformy Web v položkách URI přesměrování v portálu Entra nebo Azure. Při použití Entra se port nevyžaduje pro adresy localhost. Většina ostatních zprostředkovatelů OIDC vyžaduje správný port. Pokud do registrace aplikace v Entra nepřidáte identifikátor URI cesty zpětného volání po odhlášení, Entra odmítne přesměrovat uživatele zpět do aplikace a pouze ho požádá, aby zavřel okno prohlížeče.

    • RemoteSignOutPath: Požadavky přijaté na této cestě způsobí, že obslužná rutina vyvolá odhlášení pomocí schématu odhlášení.

      V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

      https://localhost/signout-oidc

      Poznámka:

      Pokud používáte ID Microsoft Entra, nastavte adresu URL pro odhlášení front-channel v portálu Entra nebo Azure. Není vyžadován port pro adresy localhost při používání Entra. Většina ostatních zprostředkovatelů OIDC vyžaduje správný port.

      oidcOptions.CallbackPath = new PathString("{PATH}");
      oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
      oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
      

      Příklady (výchozí hodnoty):

      oidcOptions.CallbackPath = new PathString("/signin-oidc");
      oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
      oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
      
  • (Microsoft Azure pouze s běžným koncovým bodem): TokenValidationParameters.IssuerValidatorMnoho zprostředkovatelů OIDC pracuje s výchozím validátorem vystavitele, ale musíme počítat s parametrizovaným vystavitelem s ID tenanta ({TENANT ID}) vráceným https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. Další informace najdete v tématu SecurityTokenInvalidIssuerException s OpenID Connect a koncovým bodem Azure AD "common" (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Pouze pro aplikace používající Microsoft Entra ID nebo Azure AD B2C s "běžným" koncovým bodem:

    var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
    oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
    

Ukázkový kód aplikace

Zkontrolujte ukázkovou aplikaci a zkontrolujte následující funkce:

  • Automatická neinteraktivní aktualizace tokenů pomocí vlastního cookie aktualizačního modulu (CookieOidcRefresher.cs).
  • Volání projektu AddAuthenticationStateSerialization serveru pro přidání zprostředkovatele stavu ověřování na straně serveru, který používá PersistentComponentState k toku stav ověřování do klienta. Klient volá AddAuthenticationStateDeserialization deserializaci a používá stav ověřování předaný serverem. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.
  • Požadavky na server Blazor Web App jsou proxidovány do projektu back-endového webového rozhraní API (MinimalApiJwt). MapForwarder Program v souboru přidává přímé předávání požadavků HTTP, které odpovídají zadanému vzoru konkrétnímu cíli, pomocí výchozí konfigurace odchozího požadavku, přizpůsobených transformací a výchozího klienta HTTP:
    • Při vykreslování komponenty Weather na serveru tato komponenta používá třídu ServerWeatherForecaster k proxy žádosti o data o počasí pomocí přístupového tokenu uživatele. IHttpContextAccessor.HttpContext určuje, jestli je HttpContext k dispozici pro použití metodou GetWeatherForecastAsync. Další informace najdete v tématu ASP.NET Core Razor komponenty.
    • Při vykreslení komponenty v klientovi používá ClientWeatherForecaster komponenta implementaci služby, která používá předkonfigurované HttpClient (v souboru klientského Program projektu) k volání webového rozhraní API do projektu serveru. Minimální koncový bod rozhraní API (/weather-forecast) definovaný v souboru projektu Program serveru transformuje požadavek pomocí přístupového tokenu uživatele k získání dat o počasí.
  • Automatická neinteraktivní aktualizace tokenů pomocí vlastního cookie aktualizačního modulu (CookieOidcRefresher.cs).
  • PersistingAuthenticationStateProvider Třída (PersistingAuthenticationStateProvider.cs) je serverová stranaAuthenticationStateProvider, která používá PersistentComponentState k toku stav ověřování do klienta, což je opraveno po dobu životnosti aplikace WebAssembly.
  • Požadavky na server Blazor Web App jsou proxidovány do projektu back-endového webového rozhraní API (MinimalApiJwt). MapForwarder Program v souboru přidává přímé předávání požadavků HTTP, které odpovídají zadanému vzoru konkrétnímu cíli, pomocí výchozí konfigurace odchozího požadavku, přizpůsobených transformací a výchozího klienta HTTP:
    • Při vykreslování komponenty Weather na serveru tato komponenta používá třídu ServerWeatherForecaster k proxy žádosti o data o počasí pomocí přístupového tokenu uživatele. IHttpContextAccessor.HttpContext určuje, jestli je HttpContext k dispozici pro použití metodou GetWeatherForecastAsync. Další informace najdete v ASP.NET Core Razor komponentách.
    • Při vykreslení komponenty v klientovi používá ClientWeatherForecaster komponenta implementaci služby, která používá předkonfigurované HttpClient (v souboru klientského Program projektu) k volání webového rozhraní API do projektu serveru. Minimální koncový bod rozhraní API (/weather-forecast) definovaný v souboru projektu Program serveru transformuje požadavek pomocí přístupového tokenu uživatele k získání dat o počasí.

Další informace o (webových) voláních rozhraní API pomocí abstrakcí služby v Blazor Web Apps najdete v tématu Blazor ASP.NET Core.

Projekt na straně Blazor Web App klienta (BlazorWebAppOidc.Client)

Projekt BlazorWebAppOidc.Client je projekt Blazor Web Appna straně klienta .

Klient volá AddAuthenticationStateDeserialization deserializaci a používá stav ověřování předaný serverem. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.

PersistentAuthenticationStateProvider Třída (PersistentAuthenticationStateProvider.cs) je na straně AuthenticationStateProvider klienta, která určuje stav ověřování uživatele vyhledáním dat uložených na stránce, když byla vykreslena na serveru. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.

Pokud se uživatel potřebuje přihlásit nebo odhlásit, vyžaduje se opětovné načtení celé stránky.

Ukázková aplikace poskytuje jenom uživatelské jméno a e-mail pro účely zobrazení. Nezahrnuje tokeny, které se ověřují na serveru při provádění následných požadavků, které fungují samostatně s využitím cookie požadavků, které jsou součástí požadavků na HttpClient server.

Projekt back-endového webového rozhraní API (MinimalApiJwt)

Projekt MinimalApiJwt je back-endové webové rozhraní API pro více front-endových projektů. Projekt nakonfiguruje minimální koncový bod rozhraní API pro data o počasí. Požadavky z Blazor Web App projektu na straně serveru (BlazorWebAppOidc) se proxiují do MinimalApiJwt projektu.

Konfigurace

Nakonfigurujte projekt v JwtBearerOptionsAddJwtBearer volání v souboru projektu Program :

  • Audience: Nastaví cílovou skupinu pro jakýkoli přijatý token OIDC.

    jwtOptions.Audience = "{APP ID URI}";
    

    Poznámka:

    Pokud používáte ID Microsoft Entra, porovnejte hodnotu pouze s cestou identifikátoru URI ID aplikace , nakonfigurovanou při přidávání oboru Weather.Get pod Zveřejnění rozhraní API v portálu Azure nebo Entra.

    Příklad:

    Identifikátor URI ID aplikace ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}

    • Název adresáře ({DIRECTORY NAME}): contoso
    • ID{CLIENT ID} aplikace (klienta): 00001111-aaaa-2222-bbbb-3333cccc4444
    jwtOptions.Audience = "https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444";
    

    Předchozí příklad se týká aplikace zaregistrované v tenantovi s typem tenanta AAD B2C. Pokud je aplikace zaregistrovaná v tenantovi ME-ID, identifikátor URI ID aplikace se liší, a proto se cílová skupina liší.

    Příklad:

    Identifikátor URI ID aplikace ({APP ID URI}): api://{CLIENT ID} s ID aplikace (klient) ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444

    jwtOptions.Audience = "api://00001111-aaaa-2222-bbbb-3333cccc4444";
    
  • Authority: Nastaví oprávnění pro provádění volání OIDC. Porovná hodnotu s autoritou nakonfigurovanou pro obslužnou rutinu OIDC v BlazorWebAppOidc/Program.cs:

    jwtOptions.Authority = "{AUTHORITY}";
    

    Příklad:

    Autorita (): {AUTHORITY} (https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/používá ID aaaabbbb-0000-cccc-1111-dddd2222eeeetenanta)

    jwtOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
    

    Předchozí příklad se týká aplikace zaregistrované v tenantovi s typem tenanta AAD B2C. Pokud je aplikace zaregistrovaná v tenantovi ME-ID, měla by se autorita shodovat s issurerem (iss) JWT vráceným poskytovatelem identity :

    jwtOptions.Authority = "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/";
    

Minimální rozhraní API pro data o počasí

Zabezpečený koncový bod pro předpověď počasí v souboru projektu Program :

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();

Metoda RequireAuthorization rozšíření vyžaduje autorizaci pro definici trasy. Pro všechny kontrolery, které přidáte do projektu, přidejte [Authorize] atribut do kontroleru nebo akce.

Přesměrování na stránku home při odhlášení

Komponenta LogInOrOut (Layout/LogInOrOut.razor) nastaví skryté pole pro zpáteční adresu URL (ReturnUrl) na aktuální adresu URL (currentURL). Když se uživatel z aplikace odhlásí, poskytovatel identity vrátí uživatele na stránku, ze které se odhlásil. Pokud se uživatel odhlásí ze zabezpečené stránky, vrátí se na stejnou zabezpečenou stránku a odešle se zpět prostřednictvím procesu ověřování. Tento tok ověřování je přiměřený, když uživatelé potřebují pravidelně měnit účty.

Případně použijte následující LogInOrOut komponentu, která při odhlášení nezadává zpáteční adresu URL.

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 @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>

Aktualizace tokenu

Implementace vlastního cookie refresheru (CookieOidcRefresher.cs) aktualizuje deklarace identity uživatele automaticky, jakmile vyprší jejich platnost. Aktuální implementace očekává, že obdrží token ID z koncového bodu tokenu výměnou za obnovovací token. Nároky v tomto ID tokenu se pak použijí k přepsání nároků uživatele.

Ukázková implementace neobsahuje kód pro vyžádání deklarací identity z koncového bodu UserInfo při aktualizaci tokenu. Další informace najdete v tématu BlazorWebAppOidc AddOpenIdConnect with GetClaimsFromUserInfoEndpoint = true doesn't propogate role claims to client (dotnet/aspnetcore #58826).

Poznámka:

Někteří poskytovatelé identityvrací přístupový token pouze při použití obnovovacího tokenu. CookieOidcRefresher je možné aktualizovat pomocí další logiky, abyste mohli dál používat předchozí sadu deklarací identity uložených v ověřovacím cookie nebo použít přístupový token k vyžádání deklarací identity z koncového bodu UserInfo.

Kryptografická nešifrovaná

Nonce je řetězcová hodnota, která přidruží relaci klienta k tokenu ID pro zmírnění útoků přehrání.

Pokud při vývoji a testování ověřování dojde k chybě, použijte pro každé testovací spuštění novou relaci prohlížeče InPrivate nebo incognito, bez ohledu na to, jak malá je změna provedená v aplikaci nebo testovacím uživateli, protože zastaralá data můžou vést k nečekané cookie chybě. Další informace najdete v části Soubory cookie a data webu.

Nepožaduje se ani nepoužívá, když se obnovovací token vymění za nový přístupový token. V ukázkové aplikaci CookieOidcRefresher se (CookieOidcRefresher.cs) záměrně nastaví OpenIdConnectProtocolValidator.RequireNonce na false.

Aplikační role pro aplikace, které nejsou zaregistrované v Microsoft Entra (ME-ID)

Tato část se týká aplikací, které jako poskytovatele nepoužívají MICROSOFT Entra ID (ME-ID).identity U aplikací registrovaných pomocí ME-ID se podívejte na role aplikací zaregistrovaných v části Microsoft Entra (ME-ID).

Nakonfigurujte typ deklarace identity role (TokenValidationParameters.RoleClaimType) v OpenIdConnectOptions :Program.cs

oidcOptions.TokenValidationParameters.RoleClaimType = "{ROLE CLAIM TYPE}";

Pro mnoho zprostředkovatelů OIDC identity je roletyp deklarace role . Zkontrolujte správnou hodnotu v dokumentaci poskytovatele identity .

UserInfo Nahraďte třídu v BlazorWebAppOidc.Client projektu následující třídou.

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.");
}

V tuto chvíli Razor můžou komponenty přijímat autorizaci na základě rolí a na základě zásad. Role aplikace se zobrazují v role deklarací identity, jedna deklarace identity na roli.

Aplikační role pro aplikace zaregistrované v Microsoft Entra (ME-ID)

Pokyny v této části použijte k implementaci aplikačních rolí, skupin zabezpečení ME-ID a předdefinovaných rolí správce ME-ID pro aplikace pomocí Microsoft Entra ID (ME-ID).

Přístup popsaný v této části konfiguruje ME-ID pro odesílání skupin a rolí v hlavičce ověřování cookie . Pokud jsou uživatelé členem pouze několika skupin zabezpečení a rolí, měl by následující přístup fungovat pro většinu hostitelských platforem, aniž by narazili na problém, kdy hlavičky jsou příliš dlouhé, například u hostování služby IIS s výchozím limitem délky záhlaví 16 kB (MaxRequestBytes). Pokud je délka záhlaví problém kvůli vysokému členství ve skupině nebo členství v rolích, nedoporučujeme postupovat podle pokynů v této části ve prospěch implementace Microsoft Graphu pro získání skupin a rolí uživatele z ME-ID samostatně, což je přístup, který nefoukne velikost ověřování cookie. Další informace naleznete v tématu Chybný požadavek – Požadavek je příliš dlouhý – Server IIS (dotnet/aspnetcore #57545).

Nakonfigurujte typ deklarace identity role (TokenValidationParameters.RoleClaimType) v OpenIdConnectOptions souboru Program.cs. Nastavte hodnotu na roles:

oidcOptions.TokenValidationParameters.RoleClaimType = "roles";

I když nemůžete přiřadit role skupinám bez účtu ME-ID Premium, můžete přiřadit role uživatelům a přijímat deklarace rolí pro uživatele se standardním účtem Azure. Pokyny v této části nevyžadují účet ME-ID Premium.

Při práci s výchozím adresářem postupujte podle pokynů v tématu Přidání rolí aplikace do vaší aplikace a jejich přijetí v tokenu (dokumentace k ME-ID) a nakonfigurujte a přiřaďte role. Pokud nepracujete s výchozím adresářem, upravte manifest aplikace na webu Azure Portal a nastavte role aplikace ručně v appRoles položce souboru manifestu. Další informace najdete v tématu Konfigurace deklarace identity role (dokumentace k ME-ID).

Skupiny zabezpečení Azure uživatele přicházejí do groups deklarací identity a předdefinovaná přiřazení rolí správce ME-ID dorazí do známých ID (wids) deklarací identity. Hodnoty obou typů deklarací identity jsou identifikátory GUID. Při přijetí aplikací je možné tyto deklarace identity použít k vytvoření autorizace rolí a zásad v Razor komponentách.

V manifestu aplikace na webu Azure Portal nastavte groupMembershipClaims atribut na All. Výsledkem je All , že ME-ID odesílá všechny skupiny zabezpečení/distribuce (groups deklarace identity) a role (wids deklarace identity) přihlášeného uživatele. Nastavení atributu groupMembershipClaims :

  1. Otevřete registraci aplikace na webu Azure Portal.
  2. Na bočním panelu vyberte Spravovat>manifest.
  3. Vyhledejte groupMembershipClaims atribut.
  4. Nastavte hodnotu na All ("groupMembershipClaims": "All").
  5. Vyberte tlačítko Uložit.

UserInfo Nahraďte třídu v BlazorWebAppOidc.Client projektu následující třídou.

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.");
}

V tomto okamžiku Razor můžou komponenty přijímat autorizaci na základě rolí a zásad:

  • Role aplikace se zobrazují v roles deklarací identity, jedna deklarace identity na roli.
  • Skupiny zabezpečení se zobrazují v groups deklarací identity, jedna deklarace identity na skupinu. Identifikátory GUID skupin zabezpečení se zobrazí na webu Azure Portal při vytváření skupiny zabezpečení a zobrazí se při výběru Identity>.
  • Předdefinované role správce ME-ID se zobrazují v wids deklarací identity, jedna deklarace identity na roli. Deklarace wids identity s hodnotou b79fbf4d-3ef9-4689-8143-76b194e85509 je vždy odeslána ME-ID pro účty mimo host tenanta a neodkazuje na roli správce. Identifikátory GUID rolí správce (ID šablon rolí) se zobrazí na webu Azure Portal při výběru rolí a správců a tří teček (...) >Popis uvedené role ID šablon rolí jsou uvedená také v předdefinovaných rolích Microsoft Entra (dokumentace k Entra).

Odstraňování potíží

Protokolování

Serverová aplikace je standardní aplikace ASP.NET Core. Informace o povolení nižší úrovně protokolování v serverové aplikaci najdete v pokynech k protokolování ASP.NET Core.

Pokud chcete povolit protokolování ladění nebo trasování pro Blazor WebAssembly ověřování, přečtěte si Core Blazor pomocí selektoru verze článku nastaveného na ASP.NET Core 7.0 nebo novější.

Běžné chyby

  • Chybná konfigurace aplikace nebo Identity poskytovatele (IP)

    Nejčastější chyby jsou způsobené nesprávnou konfigurací. Tady je několik příkladů:

    • V závislosti na požadavcích scénáře brání chybějící nebo nesprávné autoritě, instanci, ID tenanta, doméně tenanta, ID klienta nebo identifikátoru URI přesměrování, aby aplikace ověřoval klienty.
    • Nesprávné obory požadavků brání klientům v přístupu ke koncovým bodům webového rozhraní API serveru.
    • Nesprávná nebo chybějící oprávnění rozhraní API serveru brání klientům v přístupu ke koncovým bodům webového rozhraní API serveru.
    • Spuštění aplikace na jiném portu, než je nakonfigurované v identifikátoru URI přesměrování registrace aplikace IP adresy. Všimněte si, že port není nutný pro MICROSOFT Entra ID a aplikaci spuštěnou localhost na adrese pro testování vývoje, ale konfigurace portu aplikace a port, na kterém je aplikace spuštěná, se musí shodovat s neadresoulocalhost .

    Pokrytí konfigurace v tomto článku ukazuje příklady správné konfigurace. Pečlivě zkontrolujte konfiguraci, která hledá aplikaci a nesprávnou konfiguraci IP adres.

    Pokud se konfigurace zobrazí správně:

    • Analyzujte protokoly aplikace.

    • Prozkoumejte síťový provoz mezi klientskou aplikací a IP nebo serverovou aplikací pomocí vývojářských nástrojů prohlížeče. Často je přesná chybová zpráva nebo zpráva s povědomím o příčině problému vrácena klientovi ip adresou nebo serverovou aplikací po provedení požadavku. Vývojářské nástroje pokyny najdete v následujících článcích:

    Tým dokumentace reaguje na zpětnou vazbu a chyby v článcích (otevřete problém z oddílu Pro zpětnou vazbu na této stránce ), ale nemůže poskytnout podporu k produktům. K dispozici je několik veřejných fór podpory, která vám pomůžou s řešením potíží s aplikací. Doporučujeme následující:

    Předchozí fóra nejsou vlastněna ani řízena Společností Microsoft.

    V případě zpráv o chybách rozhraní bez zabezpečení, nerozlišujících a nedůvěryhodných reprodukovatelných chyb otevřete problém s produktovou jednotkou ASP.NET Core. Neotevírejte problém s produktovou jednotkou, dokud důkladně neprošetříte příčinu problému a nemůžete ho vyřešit sami a s pomocí komunity na veřejném fóru podpory. Produktová jednotka nedokáže řešit potíže s jednotlivými aplikacemi, které jsou poškozené kvůli jednoduché chybné konfiguraci nebo případům použití zahrnujícím služby třetích stran. Pokud je sestava citlivá nebo důvěrná v povaze nebo popisuje potenciální chybu zabezpečení v produktu, který může cyberattackers zneužít, přečtěte si téma Hlášení problémů se zabezpečením a chyb (dotnet/aspnetcore úložiště GitHub).

  • Neautorizovaný klient pro ME-ID

    info: Autorizace Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] selhala. Tyto požadavky nebyly splněny: DenyAnonymousAuthorizationRequirement: Vyžaduje ověřeného uživatele.

    Chyba zpětného volání přihlášení z ME-ID:

    • Chyba: unauthorized_client
    • Popis: AADB2C90058: The provided application is not configured to allow public clients.

    Řešení chyby:

    1. Na webu Azure Portal přejděte k manifestu aplikace.
    2. allowPublicClient Nastavte atribut na null nebo true.

Soubory cookie a data webu

Soubory cookie a data webu se můžou uchovávat v aktualizacích aplikací a kolidovat s testováním a odstraňováním potíží. Při provádění změn kódu aplikace, změn uživatelského účtu u poskytovatele nebo změn konfigurace aplikace poskytovatele zrušte následující:

  • Soubory cookie přihlašování uživatelů
  • Soubory cookie aplikace
  • Uložená a uložená data lokality v mezipaměti

Jedním z přístupů k tomu, aby se zabránilo zasahování souborů cookie a dat webu do testování a řešení potíží, je:

  • Konfigurace prohlížeče
    • K testování můžete použít prohlížeč, který můžete nakonfigurovat tak, aby při každém zavření prohlížeče odstranil všechna cookie data a data webu.
    • Ujistěte se, že je prohlížeč zavřený ručně nebo integrované vývojové prostředí (IDE) pro všechny změny aplikace, testovacího uživatele nebo konfigurace poskytovatele.
  • Pomocí vlastního příkazu otevřete prohlížeč v režimu InPrivate nebo Incognito v sadě Visual Studio:
    • V dialogovém okně Spustit v sadě Visual Studio otevřete dialogové okno Procházet.
    • Vyberte tlačítko Přidat.
    • Do pole Program zadejte cestu k prohlížeči. Následující spustitelné cesty jsou typická umístění instalace pro Windows 10. Pokud je váš prohlížeč nainstalovaný v jiném umístění nebo nepoužíváte Windows 10, zadejte cestu ke spustitelnému souboru prohlížeče.
      • 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
    • V poli Argumenty zadejte možnost příkazového řádku, kterou prohlížeč používá k otevření v režimu InPrivate nebo Anonymní režim. Některé prohlížeče vyžadují adresu URL aplikace.
      • Microsoft Edge: Použijte -inprivate.
      • Google Chrome: Použijte --incognito --new-window {URL}, kde {URL} zástupný symbol je adresa URL k otevření (například https://localhost:5001).
      • Mozilla Firefox: Použijte -private -url {URL}, kde {URL} zástupný symbol je adresa URL k otevření (například https://localhost:5001).
    • Do pole Popisný název zadejte název. Například Firefox Auth Testing.
    • Vyberte tlačítko OK.
    • Pokud se chcete vyhnout výběru profilu prohlížeče pro každou iteraci testování pomocí aplikace, nastavte profil jako výchozí tlačítkem Nastavit jako výchozí .
    • Ujistěte se, že integrované vývojové prostředí (IDE) zavřel prohlížeč pro všechny změny aplikace, testovacího uživatele nebo konfigurace poskytovatele.

Upgrady aplikací

Funkční aplikace může selhat okamžitě po upgradu sady .NET Core SDK na vývojovém počítači nebo změně verzí balíčků v aplikaci. V některých případech můžou inkoherentní balíčky přerušit aplikaci při provádění hlavních upgradů. Většinu těchto problémů je možné vyřešit pomocí těchto pokynů:

  1. Vymažte mezipaměti balíčků NuGet místního systému spuštěním dotnet nuget locals all --clear z příkazového prostředí.
  2. Odstraňte složky a bin složky projektuobj.
  3. Obnovte a znovu sestavte projekt.
  4. Před opětovným nasazením aplikace odstraňte všechny soubory ve složce nasazení na serveru.

Poznámka:

Použití verzí balíčků nekompatibilních s cílovou architekturou aplikace se nepodporuje. Informace o balíčku potřebujete pomocí galerie NuGet nebo Průzkumníka balíčků FuGet.

Spuštění serverové aplikace

Při testování a řešení potíží Blazor Web Appse ujistěte, že aplikaci spouštíte ze serverového projektu.

Kontrola uživatele

Následující UserClaims komponentu lze použít přímo v aplikacích nebo sloužit jako základ pro další přizpůsobení.

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;
    }
}

Další materiály