Dela via


Skydda en ASP.NET Core Blazor Web App med OpenID Connect (OIDC)

Anteckning

Det här är inte den senaste versionen av den här artikeln. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Viktig

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Den här artikeln beskriver hur du skyddar en Blazor Web App med OpenID Connect (OIDC) med hjälp av en exempelapp på dotnet/blazor-samples GitHub-lagringsplats (.NET 8 eller senare) (hur du laddar ned).

Den här versionen av artikeln beskriver implementering av OIDC utan att använda -serverdelen för klientdelsmönstret (BFF). BFF-mönstret är användbart för att göra autentiserade begäranden till externa tjänster. Ändra artikelversionsväljaren till OIDC med BFF-mönster om appens specifikation kräver att BFF-mönstret används.

Följande specifikation omfattas:

  • Blazor Web App använder det automatiska renderingsläget med global interaktivitet.
  • Tjänster för anpassade autentiseringstillståndsleverantörer används av server- och klientappar för att fånga användarens autentiseringstillstånd och överföra det mellan servern och klienten.
  • Den här appen är en startpunkt för alla OIDC-autentiseringsflöden. OIDC konfigureras manuellt i appen och förlitar sig inte på Microsoft Entra-ID eller Microsoft Identity Web-paket, och exempelappen kräver inte heller Microsoft Azure värd. Exempelappen kan dock användas med Entra, Microsoft Identity Web och hanteras i Azure.
  • Automatisk icke-interaktiv tokenförnyelse.
  • Anropar säkert ett (webb)API i serverprojektet för data.

En alternativ upplevelse med Microsoft Authentication Library för .NET, Microsoft Identity Weboch Microsoft Entra IDfinns i Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID.

Exempelapp

Exempelappen består av två projekt:

  • BlazorWebAppOidc: Projekt på serversidan för Blazor Web App, som innehåller ett exempel Minimal API- slutpunkt för väderdata.
  • BlazorWebAppOidc.Client: Projektet på klientsidan för Blazor Web App.

Få åtkomst till exempelapparna via den senaste versionsmappen från lagringsplatsens rot med följande länk. Projekten finns i mappen BlazorWebAppOidc för .NET 8 eller senare.

Visa eller ladda ned exempelkod (hur du laddar ned)

Blazor Web App projekt på serversidan (BlazorWebAppOidc)

Det BlazorWebAppOidc projektet är projektet på serversidan för Blazor Web App.

Den BlazorWebAppOidc.http filen kan användas för att testa väderdatabegäran. Observera att BlazorWebAppOidc projektet måste köras för att testa slutpunkten och att slutpunkten är hårdkodad i filen. Mer information finns i Använda .http-filer i Visual Studio 2022.

Konfiguration

I det här avsnittet beskrivs hur du konfigurerar exempelappen.

Anteckning

För Microsoft Entra-ID eller Azure AD B2C kan du använda AddMicrosoftIdentityWebApp från Microsoft Identity Web (Microsoft.Identity.Web NuGet-paket, API-dokumentation), som lägger till både OIDC- och Cookie-autentiseringshanterare med lämpliga standardvärden. Exempelappen och vägledningen i det här avsnittet använder inte Microsoft Identity Web. Vägledningen visar hur du konfigurerar OIDC-hanteraren manuellt för alla OIDC-leverantörer. Mer information om hur du implementerar Microsoft Identity Web finns i de länkade resurserna.

Upprätta klienthemligheten

Varning

Lagra inte apphemligheter, anslutningssträngar, autentiseringsuppgifter, lösenord, personliga identifieringsnummer (PIN),privat C#/.NET-kod eller privata nycklar/token i kod på klientsidan, vilket är alltid osäker. I test-/mellanlagrings- och produktionsmiljöer bör Blazor kod på serversidan och webb-API:er använda säkra autentiseringsflöden som undviker att underhålla autentiseringsuppgifter i projektkod eller konfigurationsfiler. Förutom testning av lokal utveckling rekommenderar vi att du undviker användning av miljövariabler för att lagra känsliga data, eftersom miljövariabler inte är den säkraste metoden. För testning av lokal utveckling rekommenderas verktyget Secret Manager för att skydda känsliga data. Mer information finns i På ett säkert sätt underhålla känsliga data och autentiseringsuppgifter.

För testning av lokal utveckling använder du verktyget Secret Manager för att lagra serverappens klienthemlighet under konfigurationsnyckeln Authentication:Schemes:MicrosoftOidc:ClientSecret.

Anteckning

Om appen använder Microsoft Entra-ID eller Azure AD B2C skapar du en klienthemlighet i appens registrering i Entra- eller Azure-portalen (Hantera>certifikat & hemligheter>Ny klienthemlighet). Använd Value för den nya hemligheten i följande vägledning.

Den exempelappen har inte initierats för verktyget Secret Manager. Använd ett kommandogränssnitt, till exempel PowerShell-kommandogränssnittet Developer i Visual Studio, för att köra följande kommando. Innan du kör kommandot ändrar du katalogen med kommandot cd till serverprojektets katalog. Kommandot upprättar en identifierare för användarhemligheter (<UserSecretsId> i serverappens projektfil):

dotnet user-secrets init

Kör följande kommando för att ange klienthemligheten. Platshållaren {SECRET} är klienthemligheten som hämtas från appens registrering:

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

Om du använder Visual Studio kan du bekräfta att hemligheten har angetts genom att högerklicka på serverprojektet i Solution Explorer och välja Hantera användarhemligheter.

Konfigurera appen

Följande OpenIdConnectOptions konfiguration finns i projektets Program-fil vid anropet till AddOpenIdConnect:

  • SignInScheme: Anger det autentiseringsschema som motsvarar mellanprogrammet som ansvarar för att bevara användarens identity efter en lyckad autentisering. OIDC-hanteraren måste använda ett inloggningsschema som kan bevara användarautentiseringsuppgifter mellan begäranden. Följande rad finns bara i demonstrationssyfte. Om det utelämnas används DefaultSignInScheme som ett återställningsvärde.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Omfång för openid och profile (Scope) (valfritt): Omfången openid och profile konfigureras också som standard eftersom de krävs för att OIDC-hanteraren ska fungera, men dessa kan behöva läggas till igen om omfången ingår i Authentication:Schemes:MicrosoftOidc:Scope konfigurationen. För allmän konfigurationsvägledning, se Konfiguration i ASP.NET Core och konfiguration i ASP.NET Core Blazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: Definierar om åtkomst- och uppdateringstoken ska lagras i AuthenticationProperties efter en lyckad auktorisering. Den här egenskapen är inställd på false för att minska storleken på den slutliga autentiseringen cookie.

    oidcOptions.SaveTokens = false;
    
  • Omfång för offlineåtkomst (Scope): Omfånget offline_access krävs för uppdateringstoken.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Authority och ClientId: Anger utfärdare och klient-ID för OIDC-anrop.

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

    Exempel:

    • Behörighet ({AUTHORITY}): https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/ (använder hyresgäst-ID aaaabbbb-0000-cccc-1111-dddd2222eeee)
    • Klient-ID ({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";
    

    Exempel på "common"-auktoritet i Microsoft Azure:

    Den "gemensamma" auktoriteten ska användas för appar med flera klientorganisationer. Du kan också använda den "vanliga" myndigheten för appar med en enda klientorganisation, men en anpassad IssuerValidator krävs, vilket visas senare i det här avsnittet.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ResponseType: Konfigurerar OIDC-hanteraren för att endast utföra auktoriseringskodflödet. Implicita bidrag och hybridflöden är onödiga i det här läget. OIDC-hanteraren begär automatiskt lämpliga token med hjälp av koden som returneras från auktoriseringsslutpunkten.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    

    Anteckning

    I entra- eller Azure-portalens implicit beviljande och hybridflöden appregistreringskonfiguration, markerar inte antingen kryssrutan för auktoriseringsslutpunkten för att returnera åtkomsttoken eller ID-token.

  • MapInboundClaims och konfiguration av NameClaimType och RoleClaimType: Många OIDC-servrar använder "name" och "role" i stället för SOAP/WS-Fed standardvärden i ClaimTypes. När MapInboundClaims är inställt på falseutför hanteraren inte anspråksmappningar och anspråksnamnen från JWT används direkt av appen. I följande exempel ställs rollanspråkstypen in på "roles", vilket passar för Microsoft Entra ID (ME-ID). Mer information finns i dokumentationen för din identity provider.

    Anteckning

    MapInboundClaims måste anges till false för de flesta OIDC-leverantörer, vilket förhindrar att anspråk byts namn.

    oidcOptions.MapInboundClaims = false;
    oidcOptions.TokenValidationParameters.NameClaimType = "name";
    oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
    
  • Sökvägskonfiguration: Sökvägar måste matcha omdirigerings-URI:n (återanrop för inloggning) och omdirigering efter utloggning (återanrop efter utloggning) som konfigurerats när applikationen registreras hos OIDC-leverantören. I Azure-portalen konfigureras sökvägarna på bladet autentisering i appens registrering. Både inloggnings- och utloggningssökvägarna måste registreras som omdirigerings-URI:er. Standardvärdena är /signin-oidc och /signout-callback-oidc.

    • CallbackPath: Sökvägen för begäran i appens bassökväg där användaragenten returneras.

      Konfigurera återkopplingssökvägen efter utloggning i appens OIDC-leverantörsregistrering. I följande exempel är platshållaren {PORT} appens port:

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

      Anteckning

      En port krävs inte för localhost adresser när du använder Microsoft Entra-ID. De flesta andra OIDC-leverantörer kräver rätt port.

    • SignedOutCallbackPath (konfigurationsnyckel: "SignedOutCallbackPath"): Begärans sökväg inom appens bassökväg som fångas upp av OIDC-hanteraren, där användaragenten först returneras efter utloggning från identity-leverantören. Exempelappen anger inte något värde för sökvägen eftersom standardvärdet "/signout-callback-oidc" används. Efter att ha uppsnappat begäran omdirigerar OIDC-hanteraren till SignedOutRedirectUri eller RedirectUri, om detta anges.

      Konfigurera den utloggade motringningssökvägen i appens OIDC-providerregistrering. I följande exempel är platshållaren {PORT} appens port:

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

      Anteckning

      När du använder Microsoft Entra ID anger du sökvägen i konfigurationen för Web-plattformens omdirigerings-URI-poster i Entra- eller Azure-portalen. En port krävs inte för localhost adresser när du använder Entra. De flesta andra OIDC-leverantörer kräver rätt port. Om du inte lägger till URI för den utloggade återanropsvägen i appens registrering i Entra, vägrar Entra att dirigera användaren tillbaka till appen och uppmanar dem istället att bara stänga webbläsarfönstret.

    • RemoteSignOutPath: Begäranden som tas emot på den här sökvägen gör att hanteraren anropar utloggning med hjälp av utloggningsschemat.

      I följande exempel är platshållaren {PORT} appens port:

      https://localhost/signout-oidc

      Anteckning

      När du använder Microsoft Entra-ID anger du url:en för utloggning Front-channel i Entra- eller Azure-portalen. En port krävs inte för localhost adresser när du använder Entra. De flesta andra OIDC-leverantörer kräver rätt port.

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

      Exempel (standardvärden):

      oidcOptions.CallbackPath = new PathString("/signin-oidc");
      oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
      oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
      
  • (Endast Microsoft Azure med den "vanliga" slutpunkten) TokenValidationParameters.IssuerValidator: Många OIDC-leverantörer arbetar med standardutfärdarverifieraren, men vi måste ta hänsyn till utfärdaren som parameteriseras med klient-ID :t ({TENANT ID}) som returneras av https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. För mer information, se SecurityTokenInvalidIssuerException med OpenID Connect och Azure AD:s "common"-endpunkt (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Endast för appar som använder Microsoft Entra-ID eller Azure AD B2C med den "vanliga" slutpunkten:

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

Exempelappkod

Kontrollera exempelappen efter följande funktioner:

  • Automatisk förnyelse av den interaktionsfria tokenen med hjälp av en anpassad cookie förnyare (CookieOidcRefresher.cs).
  • Serverprojektet anropar AddAuthenticationStateSerialization för att lägga till en autentiseringsstatusleverantör på serversidan som använder PersistentComponentState för att överföra autentiseringsstatusen till klienten. Klienten anropar AddAuthenticationStateDeserialization för att deserialisera och använda autentiseringstillståndet som skickas av servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.
  • Ett exempel på begäranden till Blazor Web App för väderdata hanteras av en minimal API-slutpunkt (/weather-forecast) i filen Program (Program.cs). Slutpunkten kräver auktorisering genom att anropa RequireAuthorization. För alla kontrollanter som du lägger till i projektet lägger du till attributet [Authorize] till kontrollanten eller åtgärden.
  • Appen anropar säkert ett (webb)API i serverprojektet för väderdata:
    • När Weather återges på servern, använder komponenten ServerWeatherForecaster för att direkt hämta väderdata (inte via ett webb-API-anrop).
    • När komponenten renderas på klienten, nyttjas implementeringen av ClientWeatherForecaster-tjänsten, som använder en förkonfigurerad HttpClient (i klientprojektets Program-fil) för att göra ett webb-API-anrop till serverprojektet. En minimal API-slutpunkt (/weather-forecast) som definierats i serverprojektets Program-fil hämtar väderdata från ServerWeatherForecaster och returnerar data till klienten.
  • Automatisk förnyelse av den interaktionsfria tokenen med hjälp av en anpassad cookie förnyare (CookieOidcRefresher.cs).
  • Klassen PersistingAuthenticationStateProvider (PersistingAuthenticationStateProvider.cs) är en serverside AuthenticationStateProvider som använder PersistentComponentState för att överföra autentiseringstillståndet till klienten, vilket sedan är fastställt för hela WebAssembly-applikationens livslängd.
  • Ett exempel på begäranden till Blazor Web App för väderdata hanteras av en minimal API-slutpunkt (/weather-forecast) i filen Program (Program.cs). Slutpunkten kräver auktorisering genom att anropa RequireAuthorization. För alla kontrollanter som du lägger till i projektet lägger du till attributet [Authorize] till kontrollanten eller åtgärden.
  • Appen anropar säkert ett (webb)API i serverprojektet för väderdata:
    • När Weather återges på servern, använder komponenten ServerWeatherForecaster för att direkt hämta väderdata (inte via ett webb-API-anrop).
    • När komponenten renderas på klienten, nyttjas implementeringen av ClientWeatherForecaster-tjänsten, som använder en förkonfigurerad HttpClient (i klientprojektets Program-fil) för att göra ett webb-API-anrop till serverprojektet. En minimal API-slutpunkt (/weather-forecast) som definierats i serverprojektets Program-fil hämtar väderdata från ServerWeatherForecaster och returnerar data till klienten.

Mer information om (webb)API-anrop med hjälp av en tjänstabstraktion i Blazor Web Apps finns i Anropa ett webb-API från en ASP.NET Core Blazor-app.

Klientsidesprojekt Blazor Web App (BlazorWebAppOidc.Client)

Det BlazorWebAppOidc.Client projektet är projektet på klientsidan för Blazor Web App.

Klienten anropar AddAuthenticationStateDeserialization för att deserialisera och använda autentiseringstillståndet som skickas av servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.

Klassen PersistentAuthenticationStateProvider (PersistentAuthenticationStateProvider.cs) är en AuthenticationStateProvider på klientsidan som avgör användarens autentiseringstillstånd genom att söka efter data som sparats på sidan när den återges på servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.

Om användaren behöver logga in eller ut, krävs det en fullständig omladdning av sidan.

Exempelappen innehåller endast ett användarnamn och e-postmeddelande i visningssyfte. De innehåller inte tokens som autentiserar mot servern när efterföljande begäranden görs, vilket fungerar separat med hjälp av en cookie som ingår i HttpClient-begäranden till servern.

Den här versionen av artikeln täcker implementering av OIDC med mönstret Backend for Frontend (BFF). Ändra artikelversionsväljaren till OIDC utan BFF-mönster om appens specifikation inte kräver att BFF-mönstret används.

Följande specifikation omfattas:

  • Blazor Web App använder det automatiska renderingsläget med global interaktivitet.
  • Tjänster för anpassade autentiseringstillståndsleverantörer används av server- och klientappar för att fånga användarens autentiseringstillstånd och överföra det mellan servern och klienten.
  • Den här appen är en startpunkt för alla OIDC-autentiseringsflöden. OIDC konfigureras manuellt i appen och förlitar sig inte på Microsoft Entra-ID eller Microsoft Identity Web-paket, och exempelappen kräver inte heller Microsoft Azure värd. Exempelappen kan dock användas med Entra, Microsoft Identity Web och hanteras i Azure.
  • Automatisk icke-interaktiv tokenförnyelse.
  • BFF-mönstret (Backend for Frontend) används med hjälp av .NET Aspire för tjänstidentifiering och YARP- för proxyförfrågningar till väderprognos-slutpunkten i backend-appen.
    • Ett serverdelswebb-API använder JWT-ägarautentisering för att verifiera JWT-token som sparats av Blazor Web App i inloggnings-cookie.
    • Aspire förbättrar upplevelsen av att skapa .NET-molnbaserade appar. Det ger en konsekvent, åsiktsuppsättning med verktyg och mönster för att skapa och köra distribuerade appar.
    • YARP (Yet Another Reverse Proxy) är ett bibliotek som används för att skapa en omvänd proxyserver.

Mer information om .NET Aspirefinns i Allmän tillgänglighet för .NET Aspire: Förenkling av .NET Cloud-Native Utveckling (maj, 2024).

Förutsättning

.NET Aspire kräver Visual Studio version 17.10 eller senare.

Exempelapp

Exempelappen består av fem projekt:

  • .NET Aspire:
    • Aspire.AppHost: Används för att hantera högnivåorkestreringsproblem för appen.
    • Aspire.ServiceDefaults: Innehåller standardkonfigurationer för .NET Aspire appar som kan utökas och anpassas efter behov.
  • MinimalApiJwt: Backend-webb-API som innehåller ett Minimal API-exempel på en slutpunkt för väderdata.
  • BlazorWebAppOidc: Projektet på serversidan för Blazor Web App.
  • BlazorWebAppOidc.Client: Projektet på klientsidan för Blazor Web App.

Få åtkomst till exempelapparna via den senaste versionsmappen från lagringsplatsens rot med följande länk. Projekten finns i mappen BlazorWebAppOidcBff för .NET 8 eller senare.

Visa eller ladda ned exempelkod (hur du laddar ned)

.NET Aspire projekt

Mer information om hur du använder .NET Aspire och information om .AppHost och .ServiceDefaults projekt i exempelappen finns i .NET Aspire dokumentationen.

Bekräfta att du har uppfyllt kraven för .NET Aspire. Mer information finns i avsnittet Krav i Snabbstart: Skapa din första .NET Aspire app.

Exempelappen konfigurerar endast en osäker HTTP-startprofil (http) för användning under utvecklingstestning. Mer information, inklusive ett exempel på profiler för osäkra och säkra startinställningar, finns i Tillåt osäker transport i .NET Aspire (.NET Aspire dokumentation).

Blazor Web App projekt på serversidan (BlazorWebAppOidc)

Det BlazorWebAppOidc projektet är projektet på serversidan för Blazor Web App. Projektet använder YARP- till proxybegäranden till en slutpunkt för väderprognoser i serverdelswebb-API-projektet (MinimalApiJwt) med access_token som lagras i autentiseringen cookie.

Den BlazorWebAppOidc.http filen kan användas för att testa väderdatabegäran. Observera att BlazorWebAppOidc projektet måste köras för att testa slutpunkten och att slutpunkten är hårdkodad i filen. Mer information finns i Använda .http-filer i Visual Studio 2022.

Konfiguration

I det här avsnittet beskrivs hur du konfigurerar exempelappen.

Anteckning

För Microsoft Entra-ID eller Azure AD B2C kan du använda AddMicrosoftIdentityWebApp från Microsoft Identity Web (Microsoft.Identity.Web NuGet-paket, API-dokumentation), som lägger till både OIDC- och Cookie-autentiseringshanterare med lämpliga standardvärden. Exempelappen och vägledningen i det här avsnittet använder inte Microsoft Identity Web. Vägledningen visar hur du konfigurerar OIDC-hanteraren manuellt för alla OIDC-leverantörer. Mer information om hur du implementerar Microsoft Identity Web finns i de länkade resurserna.

Upprätta klienthemligheten

Varning

Lagra inte apphemligheter, anslutningssträngar, autentiseringsuppgifter, lösenord, personliga identifieringsnummer (PIN),privat C#/.NET-kod eller privata nycklar/token i kod på klientsidan, vilket är alltid osäker. I test-/mellanlagrings- och produktionsmiljöer bör Blazor kod på serversidan och webb-API:er använda säkra autentiseringsflöden som undviker att underhålla autentiseringsuppgifter i projektkod eller konfigurationsfiler. Förutom testning av lokal utveckling rekommenderar vi att du undviker användning av miljövariabler för att lagra känsliga data, eftersom miljövariabler inte är den säkraste metoden. För testning av lokal utveckling rekommenderas verktyget Secret Manager för att skydda känsliga data. Mer information finns i På ett säkert sätt underhålla känsliga data och autentiseringsuppgifter.

För testning av lokal utveckling använder du verktyget Secret Manager för att lagra serverappens klienthemlighet under konfigurationsnyckeln Authentication:Schemes:MicrosoftOidc:ClientSecret.

Anteckning

Om appen använder Microsoft Entra-ID eller Azure AD B2C skapar du en klienthemlighet i appens registrering i Entra- eller Azure-portalen (Hantera>certifikat & hemligheter>Ny klienthemlighet). Använd Value för den nya hemligheten i följande vägledning.

Den exempelappen har inte initierats för verktyget Secret Manager. Använd ett kommandogränssnitt, till exempel PowerShell-kommandogränssnittet Developer i Visual Studio, för att köra följande kommando. Innan du kör kommandot ändrar du katalogen med kommandot cd till serverprojektets katalog. Kommandot upprättar en identifierare för användarhemligheter (<UserSecretsId> i serverappens projektfil):

dotnet user-secrets init

Kör följande kommando för att ange klienthemligheten. Platshållaren {SECRET} är klienthemligheten som hämtas från appens registrering:

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

Om du använder Visual Studio kan du bekräfta att hemligheten har angetts genom att högerklicka på serverprojektet i Solution Explorer och välja Hantera användarhemligheter.

Konfigurera appen

Följande OpenIdConnectOptions konfiguration finns i projektets Program-fil vid anropet till AddOpenIdConnect:

  • SignInScheme: Anger det autentiseringsschema som motsvarar mellanprogrammet som ansvarar för att bevara användarens identity efter en lyckad autentisering. OIDC-hanteraren måste använda ett inloggningsschema som kan bevara användarautentiseringsuppgifter mellan begäranden. Följande rad finns bara i demonstrationssyfte. Om det utelämnas används DefaultSignInScheme som ett återställningsvärde.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Omfång för openid och profile (Scope) (valfritt): Omfången openid och profile konfigureras också som standard eftersom de krävs för att OIDC-hanteraren ska fungera, men dessa kan behöva läggas till igen om omfången ingår i Authentication:Schemes:MicrosoftOidc:Scope konfigurationen. För allmän konfigurationsvägledning, se Konfiguration i ASP.NET Core och konfiguration i ASP.NET Core Blazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: Definierar om åtkomst- och uppdateringstoken ska lagras i AuthenticationProperties efter en lyckad auktorisering. Värdet är inställt på true för att autentisera begäranden om väderdata från serverdelswebb-API-projektet (MinimalApiJwt).

    oidcOptions.SaveTokens = true;
    
  • Omfång för offlineåtkomst (Scope): Omfånget offline_access krävs för uppdateringstoken.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Omfång för att hämta väderdata från webb-API:et (Scope): Detta är nödvändigt för att backend webb-API-projektet (MinimalApiJwt) ska kunna verifiera åtkomsttoken med bärare-JWT.

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

    Anteckning

    När du använder Microsoft Entra-ID konfigureras Weather.Get-omfånget i Azure- eller Entra-portalen under Exponera ett API-.

    Exempel:

    • App-ID-URI ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
      • Katalognamn ({DIRECTORY NAME}): contoso
      • Program-ID (klient) ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    • Räckvidd konfigurerad för väderdata från MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/Weather.Get");
    

    Föregående exempel gäller en app som är registrerad i en klientorganisation med en AAD B2C-klienttyp. Om appen är registrerad i en ME-ID klientorganisation skiljer sig app-ID-URI:n, vilket innebär att omfånget blir annorlunda.

    Exempel:

    • App ID-URI ({APP ID URI}): api://{CLIENT ID} och applikation (klient) ID ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    • Räckvidd konfigurerad för väderdata från MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("api://00001111-aaaa-2222-bbbb-3333cccc4444/Weather.Get");
    
  • Authority och ClientId: Anger utfärdare och klient-ID för OIDC-anrop.

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

    Exempel:

    • Behörighet ({AUTHORITY}): https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/ (använder hyresgäst-ID aaaabbbb-0000-cccc-1111-dddd2222eeee)
    • Klient-ID ({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";
    

    Exempel på "common"-auktoritet i Microsoft Azure:

    Den "gemensamma" auktoriteten ska användas för appar med flera klientorganisationer. Du kan också använda den "vanliga" myndigheten för appar med en enda klientorganisation, men en anpassad IssuerValidator krävs, vilket visas senare i det här avsnittet.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ResponseType: Konfigurerar OIDC-hanteraren för att endast utföra auktoriseringskodflödet. Implicita bidrag och hybridflöden är onödiga i det här läget. OIDC-hanteraren begär automatiskt lämpliga token med hjälp av koden som returneras från auktoriseringsslutpunkten.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    

    Anteckning

    När du använder Microsoft Entra-ID ska du inte markera kryssrutan för auktoriseringsslutpunkten för att returnera Åtkomsttoken eller ID-token i Implicit beviljande och hybridflöden appregistreringskonfiguration.

  • MapInboundClaims och konfiguration av NameClaimType och RoleClaimType: Många OIDC-servrar använder "name" och "role" i stället för SOAP/WS-Fed standardvärden i ClaimTypes. När MapInboundClaims är inställt på falseutför hanteraren inte anspråksmappningar och anspråksnamnen från JWT används direkt av appen. I följande exempel ställs rollanspråkstypen in på "roles", vilket passar för Microsoft Entra ID (ME-ID). Mer information finns i dokumentationen för din identity provider.

    Anteckning

    MapInboundClaims måste anges till false för de flesta OIDC-leverantörer, vilket förhindrar att anspråk byts namn.

    oidcOptions.MapInboundClaims = false;
    oidcOptions.TokenValidationParameters.NameClaimType = "name";
    oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
    
  • Sökvägskonfiguration: Sökvägar måste matcha omdirigerings-URI:n (återanrop för inloggning) och omdirigering efter utloggning (återanrop efter utloggning) som konfigurerats när applikationen registreras hos OIDC-leverantören. I Azure-portalen konfigureras sökvägarna på bladet autentisering i appens registrering. Både inloggnings- och utloggningssökvägarna måste registreras som omdirigerings-URI:er. Standardvärdena är /signin-oidc och /signout-callback-oidc.

    Konfigurera återställningssökvägen för utloggade i appens OIDC-provider-registrering. I följande exempel är platshållaren {PORT} appens port:

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

    Anteckning

    En port krävs inte för localhost adresser när du använder Microsoft Entra-ID. De flesta andra OIDC-leverantörer kräver rätt port.

    • SignedOutCallbackPath (konfigurationsnyckel: "SignedOutCallbackPath"): Begäransökvägen inom appens bassökväg som fångas upp av OIDC-hanteraren där användaragenten först återförs efter utloggning från leverantören identity. Exempelappen anger inte något värde för sökvägen eftersom standardvärdet "/signout-callback-oidc" används. När begäran har fångats upp omdirigerar OIDC-hanteraren till SignedOutRedirectUri eller RedirectUri, om det är angivet.

      Konfigurera den utloggade motringningssökvägen i appens OIDC-providerregistrering. I följande exempel är platshållaren {PORT} appens port:

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

      Anteckning

      När du använder Microsoft Entra-ID anger du sökvägen i Web-plattformskonfigurationens omdirigerings-URI poster i Entra- eller Azure-portalen. En port krävs inte för localhost adresser när du använder Entra. De flesta andra OIDC-leverantörer kräver rätt port. Om du inte lägger till URI:n för återkopplingssökvägen vid utloggning i appens registrering i Entra, vägrar Entra att omdirigera användaren tillbaka till appen och ber dem istället att stänga webbläsarfönstret.

    • RemoteSignOutPath: Begäranden som tas emot på den här sökvägen gör att hanteraren anropar utloggning med hjälp av utloggningsschemat.

      I följande exempel är platshållaren {PORT} appens port:

      https://localhost/signout-oidc

      Anteckning

      När du använder Microsoft Entra-ID anger du url:en för utloggning Front-channel i Entra- eller Azure-portalen. En port krävs inte för localhost adresser när du använder Entra. De flesta andra OIDC-leverantörer kräver rätt port.

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

      Exempel (standardvärden):

      oidcOptions.CallbackPath = new PathString("/signin-oidc");
      oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
      oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
      
  • (Endast Microsoft Azure med den "vanliga" slutpunkten) TokenValidationParameters.IssuerValidator: Många OIDC-leverantörer arbetar med standardutfärdarverifieraren, men vi måste ta hänsyn till utfärdaren som parameteriseras med klient-ID :t ({TENANT ID}) som returneras av https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. För mer information, se SecurityTokenInvalidIssuerException med OpenID Connect och Azure AD:s "common"-endpunkt (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Endast för appar som använder Microsoft Entra-ID eller Azure AD B2C med den "vanliga" slutpunkten:

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

Exempelappkod

Kontrollera exempelappen efter följande funktioner:

  • Automatisk förnyelse av den interaktionsfria tokenen med hjälp av en anpassad cookie förnyare (CookieOidcRefresher.cs).
  • Serverprojektet anropar AddAuthenticationStateSerialization för att lägga till en autentiseringsstatusleverantör på serversidan som använder PersistentComponentState för att överföra autentiseringsstatusen till klienten. Klienten anropar AddAuthenticationStateDeserialization för att deserialisera och använda autentiseringstillståndet som skickas av servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.
  • Begäranden till Blazor Web App skickas till serverdelswebb-API-projektet (MinimalApiJwt). MapForwarder i filen Program lägger till direkt vidarebefordran av HTTP-begäranden som matchar det angivna mönstret till ett specifikt mål med standardkonfigurationen för utgående begäran, anpassade transformeringar och http-standardklienten:
    • När komponenten Weather renderas på servern använder komponenten klassen ServerWeatherForecaster för att hantera begäran om väderdata med åtkomsttoken för användaren. IHttpContextAccessor.HttpContext avgör om en HttpContext är tillgänglig för användning av metoden GetWeatherForecastAsync. Mer information finns i ASP.NET Core Razor-komponenter.
    • När komponenten renderas på klienten, nyttjas implementeringen av ClientWeatherForecaster-tjänsten, som använder en förkonfigurerad HttpClient (i klientprojektets Program-fil) för att göra ett webb-API-anrop till serverprojektet. En minimal API-slutpunkt (/weather-forecast) som definierats i serverprojektets Program-fil transformerar begäran med användarens åtkomsttoken för att hämta väderdata.
  • Automatisk förnyelse av den interaktionsfria tokenen med hjälp av en anpassad cookie förnyare (CookieOidcRefresher.cs).
  • Klassen PersistingAuthenticationStateProvider (PersistingAuthenticationStateProvider.cs) är en serverside AuthenticationStateProvider som använder PersistentComponentState för att överföra autentiseringstillståndet till klienten, vilket sedan är fastställt för hela WebAssembly-applikationens livslängd.
  • Begäranden till Blazor Web App skickas till serverdelswebb-API-projektet (MinimalApiJwt). MapForwarder i filen Program lägger till direkt vidarebefordran av HTTP-begäranden som matchar det angivna mönstret till ett specifikt mål med standardkonfigurationen för utgående begäran, anpassade transformeringar och http-standardklienten:
    • När Weather-komponenten återges på servern använder komponenten ServerWeatherForecaster-klassen för att skapa en proxy för begäran om väderdata med användarens åtkomsttoken. IHttpContextAccessor.HttpContext avgör om en HttpContext är tillgänglig för användning av metoden GetWeatherForecastAsync. Mer information finns i ASP.NET Core Razor-komponenter.
    • När komponenten renderas på klienten, nyttjas implementeringen av ClientWeatherForecaster-tjänsten, som använder en förkonfigurerad HttpClient (i klientprojektets Program-fil) för att göra ett webb-API-anrop till serverprojektet. En minimal API-slutpunkt (/weather-forecast) som definierats i serverprojektets Program-fil transformerar begäran med användarens åtkomsttoken för att hämta väderdata.

Mer information om (webb)API-anrop med hjälp av en tjänstabstraktion i Blazor Web Apps finns i Anropa ett webb-API från en ASP.NET Core Blazor-app.

Klientsidesprojekt Blazor Web App (BlazorWebAppOidc.Client)

Det BlazorWebAppOidc.Client projektet är projektet på klientsidan för Blazor Web App.

Klienten anropar AddAuthenticationStateDeserialization för att deserialisera och använda autentiseringstillståndet som skickas av servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.

Klassen PersistentAuthenticationStateProvider (PersistentAuthenticationStateProvider.cs) är en AuthenticationStateProvider på klientsidan som avgör användarens autentiseringstillstånd genom att söka efter data som sparats på sidan när den återges på servern. Autentiseringstillståndet är fastställt under programlivslängden för WebAssembly-applikationen.

Om användaren behöver logga in eller ut, krävs det en fullständig omladdning av sidan.

Exempelappen innehåller endast ett användarnamn och e-postmeddelande i visningssyfte. De innehåller inte tokens som autentiserar mot servern när efterföljande begäranden görs, vilket fungerar separat med hjälp av en cookie som ingår i HttpClient-begäranden till servern.

Backend-webb-API-projekt (MinimalApiJwt)

MinimalApiJwt-projektet är ett bakände-webb-API för flera frontend-projekt. Projektet konfigurerar en Minimal API- slutpunkt för väderdata. Begäranden från Blazor Web App projekt på serversidan (BlazorWebAppOidc) skickas till MinimalApiJwt projektet.

Konfiguration

Konfigurera projektet i JwtBearerOptions för AddJwtBearer-anropet i projektets Program-fil:

  • Audience: Anger målgruppen för en mottagen OIDC-token.

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

    Anteckning

    När du använder Microsoft Entra-ID matchar du värdet till sökvägen till den program-ID-URI konfigurerat när du lägger till Weather.Get-omfånget under Exponera ett API i Azure- eller Entra-portalen.

    Exempel:

    App-ID URI ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}:

    • Katalognamn ({DIRECTORY NAME}): contoso
    • Program-ID (klient) ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444
    jwtOptions.Audience = "https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444";
    

    Föregående exempel gäller en app som är registrerad i en klientorganisation med en AAD B2C-klienttyp. Om appen är registrerad i en ME-ID klientorganisation skiljer sig app-ID-URI:n, vilket innebär att målgruppen skiljer sig.

    Exempel:

    App ID-URI ({APP ID URI}): api://{CLIENT ID} och applikation (klient) ID ({CLIENT ID}): 00001111-aaaa-2222-bbbb-3333cccc4444

    jwtOptions.Audience = "api://00001111-aaaa-2222-bbbb-3333cccc4444";
    
  • Authority: Anger auktoriteten för att göra OIDC-anrop. Matcha värdet med den auktoritet som konfigurerats för OIDC-hanteraren i BlazorWebAppOidc/Program.cs:

    jwtOptions.Authority = "{AUTHORITY}";
    

    Exempel:

    Behörighet ({AUTHORITY}): https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/ (använder hyresgäst-ID aaaabbbb-0000-cccc-1111-dddd2222eeee)

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

    Föregående exempel gäller en app som är registrerad i en klientorganisation med en AAD B2C-klienttyp. Om appen är registrerad i en ME-ID klientorganisation, ska myndigheten matcha utfärdaren (iss) för den JWT som returneras av identity-leverantören.

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

Minimalt API för väderdata

Säker dataslutpunkt för väderprognoser i projektets Program-fil:

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

Utökningsmetoden RequireAuthorization kräver auktorisering för routedefinitionen. För alla kontrollanter som du lägger till i projektet lägger du till attributet [Authorize] till kontrollanten eller åtgärden.

Omdirigera till sidan home vid utloggning

Komponenten LogInOrOut (Layout/LogInOrOut.razor) anger ett dolt fält för retur-URL:en (ReturnUrl) till den aktuella URL:en (currentURL). När användaren loggar ut från appen returnerar identity-providern användaren till sidan som de loggade ut från. Om användaren loggar ut från en säker sida returneras de till samma säkra sida och skickas tillbaka via autentiseringsprocessen. Det här autentiseringsflödet är rimligt när användarna behöver ändra konton regelbundet.

Du kan också använda följande LogInOrOut komponent, som inte anger någon retur-URL när du loggar ut.

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>

Tokenförnyelse

Implementeringen av den anpassade cookie uppdateraren (CookieOidcRefresher.cs) uppdaterar användarens anspråk automatiskt när de upphör att gälla. Den aktuella implementeringen förväntar sig att ta emot en ID-token från tokenslutpunkten i utbyte mot uppdateringstoken. Anspråken i denna ID-token används sedan för att skriva över användarens anspråk.

Exempelimplementeringen innehåller inte kod för att begära anspråk från UserInfo-slutpunkten vid tokenuppdatering. Mer information finns i BlazorWebAppOidc AddOpenIdConnect with GetClaimsFromUserInfoEndpoint = true doesn't propogate role claims to client (dotnet/aspnetcore #58826).

Anteckning

Vissa identity providers returnerar bara en åtkomsttoken när du använder en uppfriskningstoken. CookieOidcRefresher kan uppdateras med ytterligare logik för att fortsätta att använda den tidigare uppsättningen anspråk som lagras i autentiseringen cookie eller använda åtkomsttoken för att begära anspråk från UserInfo-slutpunkten.

Kryptografisk engångsnummer

En nonce är ett strängvärde som associerar en klients session med en ID-token för att minimera reprisattacker.

Om du får ett nonce-fel under utveckling och testning av autentisering, använd en ny privat- eller inkognito-webbläsarsession för varje testkörning, oavsett hur liten ändringen i appen eller testanvändaren är, eftersom inaktuell cookie-data kan leda till ett nonce-fel. Mer information finns i avsnittet cookies och webbplatsdata.

En nonce krävs inte eller används inte när en uppdateringstoken byts ut mot en ny åtkomsttoken. I exempelappen anger CookieOidcRefresher (CookieOidcRefresher.cs) avsiktligt OpenIdConnectProtocolValidator.RequireNonce till false.

Programroller för appar som inte har registrerats med Microsoft Entra (ME-ID)

Det här avsnittet gäller appar som inte använder Microsoft Entra-ID (ME-ID) som identity provider. Appar som registrerats med ME-ID finns i avsnittet Programroller för appar som registrerats med Microsoft Entra (ME-ID).

Konfigurera rollanspråkstypen (TokenValidationParameters.RoleClaimType) i OpenIdConnectOptions för Program.cs:

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

För många OIDC identity-leverantörer är rollanspråkstypen role. Kontrollera identity providerns dokumentation för rätt värde.

Ersätt klassen UserInfo i BlazorWebAppOidc.Client-projektet med följande klass.

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

Nu kan Razor komponenter anta rollbaserad och principbaserad auktorisering. Programroller visas i role-krav, ett anspråk per roll.

Programroller för appar som registrerats med Microsoft Entra (ME-ID)

Använd vägledningen i det här avsnittet för att implementera programroller, ME-ID säkerhetsgrupper och ME-ID inbyggda administratörsroller för appar med Microsoft Entra-ID (ME-ID).

Metoden som beskrivs i det här avsnittet konfigurerar ME-ID att skicka grupper och roller i autentiseringshuvudet cookie. När användare bara är medlemmar i ett fåtal säkerhetsgrupper och roller bör följande metod fungera för de flesta värdplattformar utan att stöta på ett problem där rubriker är för långa, till exempel med IIS-värd som har en standardgräns för sidhuvudlängd på 16 KB (MaxRequestBytes). Om rubriklängden är ett problem på grund av högt medlemskap i grupp eller roll rekommenderar vi att du inte följer riktlinjerna i det här avsnittet, utan istället implementerar Microsoft Graph för att hämta en användares grupper och roller från ME-ID separat, en metod som inte blåser upp storleken på autentiseringsinformationen cookie. Mer information finns i Felaktig begäran – Begäran för lång – IIS Server (dotnet/aspnetcore #57545).

Konfigurera rollanspråkstypen (TokenValidationParameters.RoleClaimType) i OpenIdConnectOptions för Program.cs. Ange värdet till roles:

oidcOptions.TokenValidationParameters.RoleClaimType = "roles";

Även om du inte kan tilldela roller till grupper utan ett ME-ID Premium-konto, kan du tilldela roller till användare och ta emot rollanspråk för användare med ett Standard Azure-konto. Vägledningen i det här avsnittet kräver inte ett ME-ID Premium-konto.

När du arbetar med standardkatalogen, följ anvisningarna i Lägg till approller i ditt program och motta dem i token (ME-ID dokumentation) för att konfigurera och tilldela roller. Om du inte arbetar med standardkatalogen redigerar du appens manifest i Azure-portalen för att upprätta appens roller manuellt i appRoles posten för manifestfilen. För mer information, se Konfigurera rollkravet (ME-ID dokumentation).

En användares Azure-säkerhetsgrupper anländer i groups anspråk och en användares inbyggda ME-ID administratörsrolltilldelningar kommer i välkända ID:n (wids) anspråk. Värden för båda anspråkstyperna är GUID:er. När de tas emot av appen kan dessa anspråk användas för att upprätta roll- och politiktillstånd i komponenter Razor.

I appens manifest i Azure-portalen anger du attributet groupMembershipClaims till All. Värdet All resulterar i att ME-ID skickar alla säkerhets-/distributionsgrupper (groups anspråk) och roller (wids anspråk) för den inloggade användaren. Så här anger du attributet groupMembershipClaims:

  1. Öppna appens registrering i Azure-portalen.
  2. Välj Hantera>Manifest i sidofältet.
  3. Leta upp attributet groupMembershipClaims.
  4. Ange värdet till All ("groupMembershipClaims": "All").
  5. Välj knappen Spara.

Ersätt klassen UserInfo i BlazorWebAppOidc.Client-projektet med följande klass.

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

Nu kan Razor komponenter anta rollbaserad och principbaserad auktorisering:

  • Programroller visas i roles-krav, ett anspråk per roll.
  • Säkerhetsgrupper visas i groups anspråk, ett anspråk per grupp. Säkerhetsgruppens GUID visas i Azure-portalen när du skapar en säkerhetsgrupp och visas när du väljer Identity>Översikt>Grupper>View.
  • Inbyggda ME-ID administratörsroller visas i wids anspråk, ett anspråk per roll. Anspråket wids med värdet b79fbf4d-3ef9-4689-8143-76b194e85509 skickas alltid av ME-ID för konton som inte är gästkonton hos hyresgästen och refererar inte till någon administratörsroll. GUID:er för administratörsroller (rollmalls-ID:t) visas i Azure-portalen när du väljer Roller & administratörerföljt av ellipsen (...) >Beskrivning för den angivna rollen. Rollmall-ID:er visas också i de inbyggda Microsoft Entra-rollerna (Entra-dokumentation) .

Felsöka

Skogsavverkning

Serverappen är en standardapp för ASP.NET Core. Se vägledningen för loggning i ASP.NET Core för att möjliggöra en lägre loggningsnivå i serverappen.

Information om hur du aktiverar felsökning eller spårningsloggning för Blazor WebAssembly autentisering finns i avsnittet autentiseringsloggning på klientsidan i ASP.NET Core Blazor loggning med artikelversionsväljaren inställd på ASP.NET Core 7.0 eller senare.

Vanliga fel

  • Felkonfiguration av appen eller Identity-leverantören (IP)

    De vanligaste felen orsakas av felaktig konfiguration. Följande är några exempel:

    • Beroende på kraven i scenariot förhindrar en saknad eller felaktig utfärdare, instans, klient-ID, klientdomän, klient-ID eller omdirigerings-URI en app från att autentisera klienter.
    • Felaktiga omfång för begäran hindrar klienter från att komma åt serverwebb-API-slutpunkter.
    • Felaktiga eller saknade server-API-behörigheter hindrar klienter från att komma åt serverwebb-API-slutpunkter.
    • Köra appen på en annan port än vad som har konfigurerats i omdirigerings-URI:n för IP-adressens appregistrering. Observera att en port inte krävs för Microsoft Entra-ID och en app som körs på en localhost utvecklingstestningsadress, men appens portkonfiguration och porten där appen körs måste matcha för icke-localhost adresser.

    Den här artikeln täcker exempel på korrekt konfiguration. Kontrollera noggrant konfigurationen för att hitta felkonfigurationer av appar och IP-adresser.

    Om konfigurationen verkar vara korrekt:

    • Analysera programloggar.

    • Granska nätverkstrafiken mellan klientappen och IP- eller serverappen med webbläsarens utvecklarverktyg. Ofta returneras ett exakt felmeddelande eller ett meddelande med en ledtråd till vad som orsakar problemet till klienten av IP- eller serverappen efter en begäran. Vägledning för utvecklarverktyg finns i följande artiklar:

    Dokumentationsteamet svarar på feedback och buggar i artiklar (öppna ett ärende från feedbackavsnittet på Den här sidan), men kan inte tillhandahålla produktsupport. Det finns flera offentliga supportforum som hjälper dig att felsöka en app. Vi rekommenderar följande:

    Föregående forum ägs eller kontrolleras inte av Microsoft.

    För rapporter om icke-säkerhetsrelaterade, icke-känsliga och icke-konfidentiella reproducerbara ramverksfel , skapa ett ärende med ASP.NET Core-produktgruppen. Öppna inte ett ärende med produktgruppen förrän du noggrant har undersökt orsaken till problemet och inte kan lösa det på egen hand eller med hjälp av communityn på ett offentligt supportforum. Produktenheten kan inte felsöka enskilda appar som har brutits på grund av enkel felkonfiguration eller användningsfall som rör tjänster från tredje part. Om en rapport är känslig eller konfidentiell eller beskriver en potentiell säkerhetsbrist i produkten som cyberattacker kan utnyttja kan du läsa Rapportering av säkerhetsproblem och buggar (dotnet/aspnetcore GitHub-lagringsplats).

  • Obehörig klient för ME-ID

    info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Auktoriseringen misslyckades. Dessa krav uppfylldes inte: DenyAnonymousAuthorizationRequirement: Kräver en autentiserad användare.

    Återanropsfel för inloggning från ME-ID:

    • Fel: unauthorized_client
    • Beskrivning: AADB2C90058: The provided application is not configured to allow public clients.

    Så här löser du felet:

    1. Gå till -appens manifest i Azure-portalen.
    2. Ange attributet allowPublicClient till null eller true.

Cookies och webbplatsdata

Cookies och webbplatsdata kan sparas mellan appuppdateringar och störa testning och felsökning. Rensa följande när du gör ändringar i appkoden, ändringar av användarkonton med providern eller konfigurationsändringar för providerappen:

  • Cookies för användarinloggning
  • App-kakor
  • Cachelagrade och lagrade webbplatsdata

En metod för att förhindra kvardröjande cookies och webbplatsdata från att störa testning och felsökning är att:

  • Konfigurera en webbläsare
    • Använd en webbläsare för testning som du kan konfigurera för att ta bort alla cookie och platsdata varje gång webbläsaren stängs.
    • Kontrollera att webbläsaren stängs manuellt eller av IDE för ändringar i appen, testanvändaren eller providerkonfigurationen.
  • Använd ett anpassat kommando för att öppna en webbläsare i InPrivate- eller Incognito-läge i Visual Studio:
    • Öppna dialogrutan Bläddra med från Visual Studios knapp Kör.
    • Välj knappen Lägg till.
    • Ange sökvägen till webbläsaren i fältet Program. Följande sökvägar för körbara filer är typiska installationsplatser för Windows 10. Om webbläsaren är installerad på en annan plats eller om du inte använder Windows 10 anger du sökvägen till webbläsarens körbara fil.
      • 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
    • I fältet Argument anger du det kommandoradsalternativ som webbläsaren använder för att öppna i InPrivate- eller Inkognitoläge. Vissa webbläsare kräver appens URL.
      • Microsoft Edge: Använd -inprivate.
      • Google Chrome: Använd --incognito --new-window {URL}, där platshållaren för {URL} är url:en som ska öppnas (till exempel https://localhost:5001).
      • Mozilla Firefox: Använd -private -url {URL}, där platshållaren {URL} är url:en som ska öppnas (till exempel https://localhost:5001).
    • Ange ett namn i fältet Vänligt namn. Till exempel Firefox Auth Testing.
    • Välj knappen OK.
    • Om du vill undvika att behöva välja webbläsarprofilen för varje iteration av testning med en app anger du profilen som standard med knappen Ange som standard.
    • Kontrollera att webbläsaren är stängd av IDE för alla ändringar i appen, testanvändaren eller providerkonfigurationen.

Appuppgraderingar

En fungerande app kan misslyckas omedelbart efter att ha uppgraderat .NET Core SDK på utvecklingsdatorn eller ändrat paketversioner i appen. I vissa fall kan osammanhängande paket skada en app vid genomförande av större uppgraderingar. De flesta av dessa problem kan åtgärdas genom att följa dessa instruktioner:

  1. Rensa det lokala systemets NuGet-paketcacheminnen genom att köra dotnet nuget locals all --clear från ett kommandogränssnitt.
  2. Ta bort projektets mappar bin och obj.
  3. Återställa och återskapa projektet.
  4. Ta bort alla filer i distributionsmappen på servern innan du distribuerar om appen.

Anteckning

Användning av paketversioner som inte är kompatibla med appens målramverk stöds inte. Information om ett paket finns i NuGet Gallery eller FuGet Package Explorer.

Kör serverappen

När du testar och felsöker Blazor Web Appkontrollerar du att du kör appen från serverprojektet.

Inspektera användaren

Följande UserClaims komponent kan användas direkt i appar eller fungera som grund för ytterligare anpassning.

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

Ytterligare resurser