Dela via


Skydda en värdbaserad ASP.NET Core Blazor WebAssembly-app med Identity Server

Viktig

Projektmallen Hosted Blazor WebAssembly togs bort från ramverket med lanseringen av .NET 8 (november 2023). Vägledningen i den här artikeln stöds endast för .NET 7 eller tidigare. Värdbaserade Blazor WebAssembly appar som uppgraderas varje utgåva fortsätter få produktsupport. Du kan också omstrukturera appen till en fristående Blazor WebAssembly app eller en Blazor Web App.

Den här artikeln beskriver hur du skapar en värdbaserad Blazor WebAssembly lösning som använder Duende Identity Server för att autentisera användare och API-anrop.

Viktig

Duende Software kan kräva att du betalar en licensavgift för produktionsanvändning av Duende Identity Server. Mer information finns i Migrera från ASP.NET Core 5.0 till 6.0.

Notis

Om du vill konfigurera en fristående eller värdbaserad Blazor WebAssembly app för att använda en befintlig extern Identity Server-instans följer du anvisningarna i Skydda en fristående ASP.NET Core Blazor WebAssembly-app med autentiseringsbiblioteket.

Om du vill ha ytterligare täckning av säkerhetsscenarier efter att ha läst den här artikeln, se ASP.NET Core Blazor WebAssembly ytterligare säkerhetsscenarier.

Genomgång

Underavsnitten i genomgången förklarar hur du:

  • Skapa Blazor-appen
  • Kör appen

Skapa en Blazor app

Så här skapar du ett nytt Blazor WebAssembly projekt med en autentiseringsmekanism:

  1. Skapa ett nytt projekt.

  2. Välj mallen Blazor WebAssembly App. Välj Nästa.

  3. Ange ett projektnamn utan att använda bindestreck. Bekräfta att plats är korrekt. Välj Nästa.

    Undvik att använda bindestreck (-) i projektnamnet som bryter bildandet av OIDC-appidentifieraren. Logik i Blazor WebAssembly-projektmallen använder projektnamnet för en OIDC-appidentifierare i lösningens konfiguration, och bindestreck tillåts inte i en OIDC-appidentifierare. Pascal-fall (BlazorSample) eller understreck (Blazor_Sample) är godtagbara alternativ.

  4. I dialogrutan Ytterligare information väljer du enskilda konton som -autentiseringstyp för att lagra användare i appen med hjälp av ASP.NET Cores Identity system.

  5. Markera kryssrutan ASP.NET Core Hosted.

  6. Välj knappen Skapa för att skapa appen.

Kör appen

Kör appen från Server-projektet. När du använder Visual Studio kan du antingen:

  • Välj listrutepilen bredvid knappen Kör. Öppna Konfigurera startprojekt från listrutan. Välj alternativet Enstaka startprojekt. Bekräfta eller ändra startprojektet till projekt Server.

  • Bekräfta att Server projektet är markerat i Solution Explorer innan du startar appen med någon av följande metoder:

    • Välj knappen Kör.
    • Använd felsök>starta felsökning från menyn.
    • Tryck på F5.
  • I ett kommandogränssnitt navigerar du till Server projektmappen för lösningen. Kör kommandot dotnet watch (eller dotnet run).

Delar av lösningen

I det här avsnittet beskrivs de delar av en lösning som genereras från Blazor WebAssembly-projektmallen och beskriver hur lösningens Client- och Server-projekt konfigureras som referens. Det finns ingen specifik vägledning att följa i det här avsnittet för ett grundläggande arbetsprogram om du har skapat appen med hjälp av vägledningen i avsnittet Genomgång. Vägledningen i det här avsnittet är användbar för att uppdatera en app för att autentisera och auktorisera användare. En alternativ metod för att uppdatera en app är dock att skapa en ny app från vägledningen i avsnittet Genomgång och flytta appens komponenter, klasser och resurser till den nya appen.

Server apptjänster

Det här avsnittet gäller lösningens Server app.

Följande tjänster registreras.

  • I filen Program:

    • Entity Framework Core och ASP.NET Core Identity:

      builder.Services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite( ... ));
      builder.Services.AddDatabaseDeveloperPageExceptionFilter();
      
      builder.Services.AddDefaultIdentity<ApplicationUser>(options => 
              options.SignIn.RequireConfirmedAccount = true)
          .AddEntityFrameworkStores<ApplicationDbContext>();
      
    • Identity Server med ytterligare en AddApiAuthorization hjälpmetod som konfigurerar standardprinciper för ASP.NET Core ovanpå Identity Server:

      builder.Services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Autentisering med ytterligare en AddIdentityServerJwt hjälpmetod som konfigurerar appen för att verifiera JWT-token som skapats av Identity Server:

      builder.Services.AddAuthentication()
          .AddIdentityServerJwt();
      
  • I Startup.ConfigureServices av Startup.cs:

    • Entity Framework Core och ASP.NET Core Identity:

      services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite(
              Configuration.GetConnectionString("DefaultConnection")));
      
      services.AddDefaultIdentity<ApplicationUser>(options => 
              options.SignIn.RequireConfirmedAccount = true)
          .AddEntityFrameworkStores<ApplicationDbContext>();
      

      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.

    • Identity Server med ytterligare en AddApiAuthorization hjälpmetod som konfigurerar standardprinciper för ASP.NET Core ovanpå Identity Server:

      services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Autentisering med ytterligare en AddIdentityServerJwt hjälpmetod som konfigurerar appen för att verifiera JWT-token som skapats av Identity Server:

      services.AddAuthentication()
          .AddIdentityServerJwt();
      

Anteckning

När ett enda autentiseringsschema registreras används det automatiskt som appens standardschema, och det är inte nödvändigt att ange schemat till AddAuthentication eller via AuthenticationOptions. Mer information finns i Översikt över ASP.NET Core Authentication och ASP.NET Core-meddelandet (aspnet/Meddelanden #490).

  • I filen Program:
  • I Startup.Configure av Startup.cs:
  • Identity Server Middleware exponerar OIDC-slutpunkterna (OpenID Connect):

    app.UseIdentityServer();
    
  • Autentiseringsmellanprogrammet ansvarar för att verifiera autentiseringsuppgifter för begäran och ställa in användaren i begärandekontexten:

    app.UseAuthentication();
    
  • Mellanprogram för auktorisering möjliggör auktoriseringsmöjligheter.

    app.UseAuthorization();
    

API-auktorisering

Det här avsnittet gäller lösningens Server app.

Hjälpmetoden AddApiAuthorization konfigurerar Identity Server för ASP.NET Core-scenarier. Identity Server är ett kraftfullt och utökningsbart ramverk för hantering av appsäkerhetsproblem. Identity Server exponerar onödig komplexitet för de vanligaste scenarierna. Därför tillhandahålls en uppsättning konventioner och konfigurationsalternativ som vi anser vara en bra utgångspunkt. När din autentisering behöver ändras är den fullständiga kraften i Identity Server tillgänglig för att anpassa autentiseringen efter en apps krav.

Lägga till en autentiseringshanterare för ett API som samexisterar med Identity Server

Det här avsnittet gäller lösningens Server app.

Hjälpmetoden AddIdentityServerJwt konfigurerar ett principschema för appen som standardautentiseringshanterare. Policyn är konfigurerad så att Identity kan hantera alla begäranden som dirigeras till en undersökväg i Identity URL-utrymmet under /Identity. JwtBearerHandler hanterar alla andra begäranden. Dessutom, den här metoden:

  • Registrerar en API-resurs på Identity Server med standardomfånget {PROJECT NAME}API, där platshållaren {PROJECT NAME} är projektets namn när appen skapas.
  • Konfigurerar JWT Bearer Token Middleware för att verifiera token som utfärdats av Identity Server för appen.

Väderprognoskontrollant

Det här avsnittet gäller lösningens Server app.

I WeatherForecastController (Controllers/WeatherForecastController.cs) tillämpas [Authorize]-attributet på klassen. Attributet anger att användaren måste ha behörighet baserat på standardprincipen för att få åtkomst till resursen. Standardauktoriseringsprincipen är konfigurerad för att använda standardautentiseringsschemat, som konfigureras av AddIdentityServerJwt. Hjälpmetoden konfigurerar JwtBearerHandler som standardhanterare för begäranden till appen.

Programdatabaskontext

Det här avsnittet gäller lösningens Server app.

I ApplicationDbContext (Data/ApplicationDbContext.cs) utökar DbContextApiAuthorizationDbContext<TUser> till att omfatta schemat för Identity Server. ApiAuthorizationDbContext<TUser> härleds från IdentityDbContext.

Om du vill få fullständig kontroll över databasschemat ärver du från någon av de tillgängliga IdentityDbContext-klasserna och konfigurerar kontexten så att den inkluderar Identity-schemat genom att anropa builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value) i metoden OnModelCreating.

OIDC-konfigurationskontrollant

Det här avsnittet gäller lösningens Server app.

I OidcConfigurationController (Controllers/OidcConfigurationController.cs) etableras klientslutpunkten för att hantera OIDC-parametrar.

Appinställningar

Det här avsnittet gäller lösningens Server app.

I appinställningsfilen (appsettings.json) i projektroten beskriver avsnittet IdentityServer listan över konfigurerade klienter. I följande exempel finns det en enda klient. Klientnamnet motsvarar Client appens sammansättningsnamn och mappas enligt konventionen till parametern OAuth ClientId. Profilen anger vilken apptyp som konfigureras. Profilen används internt för att driva konventioner som förenklar konfigurationsprocessen för servern.

"IdentityServer": {
  "Clients": {
    "{ASSEMBLY NAME}": {
      "Profile": "IdentityServerSPA"
    }
  }
}

Platshållaren {ASSEMBLY NAME} är Client-appens sammansättningsnamn (till exempel BlazorSample.Client).

Autentiseringspaket

Det här avsnittet gäller lösningens Client app.

När en app skapas för att använda enskilda användarkonton (Individual) tar appen automatiskt emot en paketreferens för Microsoft.AspNetCore.Components.WebAssembly.Authentication-paketet. Paketet innehåller en uppsättning primitiver som hjälper appen att autentisera användare och hämta token för att anropa skyddade API:er.

Om du lägger till autentisering i en app lägger du till Microsoft.AspNetCore.Components.WebAssembly.Authentication-paketet manuellt i appen.

Not

Mer information om hur du lägger till paket i .NET-appar finns i artiklarna under Installera och hantera paketArbetsflöde för paketförbrukning (NuGet-dokumentation). Bekräfta rätt paketversioner på NuGet.org.

HttpClient konfiguration

Det här avsnittet gäller lösningens Client app.

I Program-filen är en namngiven HttpClient konfigurerad för att tillhandahålla HttpClient instanser som inkluderar åtkomsttoken när begäranden görs till server-API:et. När lösningen skapas är namnet HttpClient{PROJECT NAME}.ServerAPI, där platshållaren {PROJECT NAME} är projektets namn.

builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI", 
        client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("{PROJECT NAME}.ServerAPI"));

Platshållaren {PROJECT NAME} är projektnamnet när lösningen skapas. Om du till exempel anger ett projektnamn för BlazorSample skapas en namngiven HttpClient av BlazorSample.ServerAPI.

Notera

Om du konfigurerar en Blazor WebAssembly app för att använda en befintlig Identity Server-instans som inte ingår i en värdbaserad Blazor lösning ändrar du HttpClient grundläggande adressregistrering från IWebAssemblyHostEnvironment.BaseAddress (builder.HostEnvironment.BaseAddress) till serverappens URL för API-auktoriseringsslutpunkt.

Stöd för API-auktorisering

Det här avsnittet gäller lösningens Client app.

Stödet för att autentisera användare är anslutet till tjänstcontainern med hjälp av tilläggsmetoden som tillhandahålls i Microsoft.AspNetCore.Components.WebAssembly.Authentication-paketet. Den här metoden konfigurerar de tjänster som krävs av appen för att interagera med det befintliga auktoriseringssystemet.

builder.Services.AddApiAuthorization();

Konfigurationen för appen läses in enligt konvention från _configuration/{client-id}. Enligt konventionen är klient-ID inställt på appens sammansättningsnamn. Den här URL:en kan ändras så att den pekar på en separat slutpunkt genom att anropa överlagringen med alternativ.

Imports fil

Det här avsnittet gäller lösningens Client app.

Namnområdet Microsoft.AspNetCore.Components.Authorization görs tillgängligt i hela appen via _Imports.razor-filen:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared

Index sida

Det här avsnittet gäller lösningens Client app.

Sidan Index (wwwroot/index.html) innehåller ett skript som definierar AuthenticationService i JavaScript. AuthenticationService hanterar lågnivåinformationen för OIDC-protokollet. Appen anropar internt metoder som definierats i skriptet för att utföra autentiseringsåtgärderna.

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

App komponent

Det här avsnittet gäller lösningens Client app.

Komponenten App (App.razor) liknar den App komponent som finns i Blazor Server appar:

  • Komponenten CascadingAuthenticationState hanterar att exponera AuthenticationState för resten av appen.
  • Komponenten AuthorizeRouteView ser till att den aktuella användaren har behörighet att komma åt en viss sida eller på annat sätt renderar RedirectToLogin komponenten.
  • Komponenten RedirectToLogin hanterar omdirigering av obehöriga användare till inloggningssidan.

På grund av ändringar i ramverket mellan versionerna av ASP.NET Core visas inte Razor-markeringen för App-komponenten (App.razor) i det här avsnittet. Om du vill kontrollera komponentens markering för en viss version använder du antingen av följande metoder:

  • Skapa en app som är förberedd för autentisering från standardprojektmallen Blazor WebAssembly för den versionen av ASP.NET Core du avser använda. Granska komponenten App (App.razor) i den genererade appen.

  • Granska komponenten App (App.razor) i referenskälla. Välj versionen från grenväljaren och sök efter komponenten i ProjectTemplates-mappen på lagringsplatsen eftersom App komponentens plats har ändrats under åren.

    Not

    Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Växla grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).

RedirectToLogin komponent

Det här avsnittet gäller lösningens Client app.

Komponenten RedirectToLogin (RedirectToLogin.razor):

  • Hanterar omdirigering av obehöriga användare till inloggningssidan.
  • Den aktuella URL:en som användaren försöker komma åt hanteras så att de kan återföras till den sidan om autentiseringen lyckas med:

Granska komponenten RedirectToLogin i -referenskälla. Platsen för komponenten ändrades över tid, så använd GitHub-sökverktyg för att hitta komponenten.

Anteckning

Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Växla grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).

LoginDisplay komponent

Det här avsnittet gäller lösningens Client app.

Komponenten LoginDisplay (LoginDisplay.razor) återges i komponenten MainLayout (MainLayout.razor) och hanterar följande beteenden:

  • För autentiserade användare:
    • Visar det aktuella användarnamnet.
    • Erbjuder en länk till användarprofilsidan i ASP.NET Core Identity.
    • Erbjuder en knapp för att logga ut från appen.
  • För anonyma användare:
    • Erbjuder möjligheten att registrera.
    • Erbjuder alternativet att logga in.

I det här avsnittet visas inte Razor-markup för LoginDisplay-komponenten på grund av ändringar i ramverket i olika versioner av ASP.NET Core. Om du vill kontrollera komponentens markering för en viss version använder du antingen av följande metoder:

  • Skapa en app som är förberedd för autentisering från standardprojektmallen Blazor WebAssembly för den versionen av ASP.NET Core du avser använda. Granska LoginDisplay komponenten i den genererade appen.

  • Granska komponenten LoginDisplay i -referenskälla. Platsen för komponenten ändrades över tid, så använd GitHub-sökverktyg för att hitta komponenten. Mallinnehållet för Hosted lika med true används.

    Not

    Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Växla grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).

Authentication komponent

Det här avsnittet gäller lösningens Client app.

Sidan som skapas av komponenten Authentication (Pages/Authentication.razor) definierar de vägar som krävs för att hantera olika autentiseringssteg.

Komponenten RemoteAuthenticatorView:

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Not

Null-berättigade referenstyper (NRTs) och .NET-kompilatorns statiska analys av null-tillstånd stöds i ASP.NET Core i .NET 6 eller senare. Före släppet av ASP.NET Core i .NET 6 visas typen string utan null-typbeteckning (?).

FetchData komponent

Det här avsnittet gäller lösningens Client app.

Komponenten FetchData visar hur du:

  • Skapa en åtkomsttoken.
  • Använd åtkomsttoken för att anropa ett skyddat resurs-API i appen Server.

I @attribute [Authorize]-direktivet anges för Blazor WebAssembly auktoriseringssystem att användaren måste ha behörighet för att kunna besöka den här komponenten. Förekomsten av attributet i Client-appen förhindrar inte att API:et på servern anropas utan rätt autentiseringsuppgifter. Server-appen måste också på rätt sätt använda [Authorize] på lämpliga slutpunkter för att skydda dem.

IAccessTokenProvider.RequestAccessToken tar hand om att begära en åtkomsttoken som kan läggas till i begäran för att anropa API:et. Om token cachelagras eller om tjänsten kan etablera en ny åtkomsttoken utan användarinteraktion lyckas tokenbegäran. Annars kommer tokenbegäran att misslyckas med en AccessTokenNotAvailableException, vilket fångas upp i en try-catch-instruktion.

För att kunna hämta den faktiska token som ska inkluderas i begäran måste appen kontrollera att begäran lyckades genom att anropa tokenResult.TryGetToken(out var token).

Om begäran lyckades fylls tokenvariabeln i med åtkomsttoken. Egenskapen AccessToken.Value för token exponerar den bokstavliga strängen som ska inkluderas i Authorization-begäranderubriken.

Om token inte kunde etableras utan användarinteraktion, vilket resulterade i en misslyckad begäran:

  • ASP.NET Core i .NET 7 eller senare: Appen navigerar till AccessTokenResult.InteractiveRequestUrl med den angivna AccessTokenResult.InteractionOptions för att tillåta uppdatering av åtkomsttoken.
  • ASP.NET Core i .NET 6 eller tidigare: Tokenresultatet innehåller en omdirigerings-URL. Om du navigerar till den här URL:en kommer användaren till inloggningssidan och tillbaka till den aktuella sidan efter en lyckad autentisering.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http

...

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }
}

Azure App Service i Linux

Ange utfärdaren explicit när du distribuerar till Azure App Service i Linux. För mer information, se Använd Identity för att säkra en webb-API-backend för SPA:er.

Namn och rollkrav med API-auktorisering

Anpassad användargenerator

Skapa en anpassad användarfabrik i Client-appen. Identity Servern skickar flera roller som en JSON-array i ett enda role påstående. En enskild roll skickas i form av ett strängvärde i anspråket. Fabriken skapar ett individuellt role krav för var och en av användarens roller.

CustomUserFactory.cs:

using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;

public class CustomUserFactory(IAccessTokenProviderAccessor accessor)
    : AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        RemoteUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(identity.RoleClaimType).ToArray();

            if (roleClaims.Any())
            {
                foreach (var existingClaim in roleClaims)
                {
                    identity.RemoveClaim(existingClaim);
                }

                var rolesElem = 
                    account.AdditionalProperties[identity.RoleClaimType];

                if (options.RoleClaim is not null && rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            var roleValue = role.GetString();

                            if (!string.IsNullOrEmpty(roleValue))
                            {
                                identity.AddClaim(
                                  new Claim(options.RoleClaim, roleValue));
                            }
        
                        }
                    }
                    else
                    {
                        var roleValue = roles.GetString();

                        if (!string.IsNullOrEmpty(roleValue))
                        {
                            identity.AddClaim(
                              new Claim(options.RoleClaim, roleValue));
                        }
                    }
                }
            }
        }

        return user;
    }
}

I appen Client registrerar du fabriken i filen Program:

builder.Services.AddApiAuthorization()
    .AddAccountClaimsPrincipalFactory<CustomUserFactory>();

I Server app anropar du AddRoles på Identity builder, som lägger till rollrelaterade tjänster.

I filen Program:

using Microsoft.AspNetCore.Identity;

...

builder.Services.AddDefaultIdentity<ApplicationUser>(options => 
    options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

I Startup.cs:

using Microsoft.AspNetCore.Identity;

...

services.AddDefaultIdentity<ApplicationUser>(options => 
    options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

Konfigurera Identity Server

Använd en av följande metoder:

Alternativ för API-auktorisering

I appen Server:

  • Konfigurera Identity Server för att lägga till name och role anspråk i ID-token och åtkomsttoken.
  • Förhindra standardmappning för roller i JWT-tokenhanteraren.

I filen Program:

using System.IdentityModel.Tokens.Jwt;

...

builder.Services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
        options.IdentityResources["openid"].UserClaims.Add("name");
        options.ApiResources.Single().UserClaims.Add("name");
        options.IdentityResources["openid"].UserClaims.Add("role");
        options.ApiResources.Single().UserClaims.Add("role");
    });

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

I Startup.cs:

using System.IdentityModel.Tokens.Jwt;
using System.Linq;

...

services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
        options.IdentityResources["openid"].UserClaims.Add("name");
        options.ApiResources.Single().UserClaims.Add("name");
        options.IdentityResources["openid"].UserClaims.Add("role");
        options.ApiResources.Single().UserClaims.Add("role");
    });

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Profiltjänst

I appen Server skapar du en ProfileService-implementering.

ProfileService.cs:

using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;

public class ProfileService : IProfileService
{
    public ProfileService()
    {
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
        context.IssuedClaims.AddRange(nameClaim);

        var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
        context.IssuedClaims.AddRange(roleClaims);

        await Task.CompletedTask;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        await Task.CompletedTask;
    }
}

I appen Server registrerar du profiltjänsten i filen Program:

using Duende.IdentityServer.Services;

...

builder.Services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

I Server-appen registrerar du profiltjänsten i Startup.ConfigureServices av Startup.cs:

using IdentityServer4.Services;

...

services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Använda auktoriseringsmekanismer

I den Client appen fungerar metoderna för komponentauktorisering just nu. Någon av auktoriseringsmekanismerna i komponenter kan använda en roll för att auktorisera användaren:

User.Identity.Name fylls i i appen Client med användarens användarnamn, vilket vanligtvis är deras inloggnings-e-postadress.

UserManager och SignInManager

Ange anspråkstypen för användaridentifierare när en serverapp kräver:

I Program.cs för ASP.NET Core i .NET 6 eller senare:

using System.Security.Claims;

...

builder.Services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

I Startup.ConfigureServices för versioner av ASP.NET Core tidigare än 6.0:

using System.Security.Claims;

...

services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

Följande WeatherForecastController loggar UserName när metoden Get anropas.

Not

I följande exempel används:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using BlazorSample.Server.Models;
using BlazorSample.Shared;

namespace BlazorSample.Server.Controllers;

[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController(ILogger<WeatherForecastController> logger, 
        UserManager<ApplicationUser> userManager) : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", 
        "Balmy", "Hot", "Sweltering", "Scorching"
    };

    [HttpGet]
    public async Task<IEnumerable<WeatherForecast>> Get()
    {
        var rng = new Random();

        var user = await userManager.GetUserAsync(User);

        if (user != null)
        {
            logger.LogInformation("User.Identity.Name: {UserIdentityName}", user.UserName);
        }

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

I föregående exempel:

  • Server projektets namnområde är BlazorSample.Server.
  • Shared projektets namnområde är BlazorSample.Shared.

Värd i Azure App Service med en anpassad domän och ett certifikat

Följande vägledning förklarar:

  • Så här distribuerar du en värdbaserad Blazor WebAssembly-app med Identity Server till Azure App Service med en anpassad domän.
  • Så här skapar och använder du ett TLS-certifikat för HTTPS-protokollkommunikation med webbläsare. Vägledningen fokuserar på att använda certifikatet med en anpassad domän, men vägledningen gäller även för användning av en standarddomän för Azure Apps, till exempel contoso.azurewebsites.net.

I det här värdscenariot använder inte samma certifikat för Duende Identity Server tokensigneringsnyckel och webbplatsens HTTPS-säkra kommunikation med webbläsare:

  • Att använda olika certifikat för dessa två krav är en bra säkerhetspraxis eftersom det isolerar privata nycklar för varje syfte.
  • TLS-certifikat för kommunikation med webbläsare hanteras oberoende av varandra utan att påverka Identity Serverns tokensignering.
  • När Azure Key Vault- tillhandahåller ett certifikat till en App Service-app för anpassad domänbindning kan Identity Server inte hämta samma certifikat från Azure Key Vault för tokensignering. Även om det är möjligt att konfigurera Identity Server för att använda samma TLS-certifikat från en fysisk sökväg, är det en dålig praxis att placera säkerhetscertifikat i källkontrollen och bör undvikas i de flesta scenarier.

I den följande vägledningen skapas ett självsignerat certifikat i Azure Key Vault enbart för Identity server-token-signering. Konfigurationen Identity Server använder nyckelvalvscertifikatet via appens CurrentUser>My certifikatarkiv. Andra certifikat som används för HTTPS-trafik med anpassade domäner skapas och konfigureras separat från Identity Server-signeringscertifikatet.

Så här konfigurerar du en app, Azure App Service och Azure Key Vault som värd för en anpassad domän och HTTPS:

  1. Skapa en App Service-plan med en plannivå på Basic B1 eller högre. App Service kräver en Basic B1 eller högre tjänstnivå för att använda anpassade domäner.

  2. Skapa ett PFX-certifikat för webbplatsens HTTPS-protokoll (Secure Browser Communication) med ett gemensamt namn på webbplatsens fullständigt kvalificerade domännamn (FQDN) som din organisation kontrollerar (till exempel www.contoso.com). Skapa certifikatet med:

    • Viktiga användningsområden
      • Validering av digital signatur (digitalSignature)
      • Nyckelchiffrering (keyEncipherment)
    • Förbättrade/utökade nyckelanvändningar
      • Klientautentisering (1.3.6.1.5.5.7.3.2)
      • Serverautentisering (1.3.6.1.5.5.7.3.1)

    Om du vill skapa certifikatet använder du någon av följande metoder eller något annat lämpligt verktyg eller en onlinetjänst:

    Anteckna lösenordet som används senare för att importera certifikatet till Azure Key Vault.

    Mer information om Azure Key Vault-certifikat finns i Azure Key Vault: Certificates.

  3. Skapa ett nytt Azure Key Vault eller använd ett befintligt nyckelvalv i din Azure-prenumeration.

  4. Importera PFX-webbplatscertifikatet i nyckelvalvets certifikatområde . Registrera certifikatets tumavtryck, som används i appens konfiguration senare.

  5. Generera ett nytt självsignerat certifikat för Identity servertokensignering i Azure Key Vault. Ge certifikatet ett certifikatnamn och ämnesnamn. Ämne anges som CN={COMMON NAME}, där platshållaren för {COMMON NAME} är certifikatets gemensamma namn. Det gemensamma namnet kan vara valfri alfanumerisk sträng. Till exempel är CN=IdentityServerSigning ett giltigt certifikat Ämne. I Utfärdandeprincip>Konfiguration av avancerad principanvänder du standardinställningarna. Registrera certifikatets tumavtryck, som används i appens konfiguration senare.

  6. Gå till Azure App Service i Azure-portalen och skapa en ny App Service med följande konfiguration:

    • Publicera inställt på Code.
    • Körningsstack inställd till appens körtid.
    • För SKU och storlekkontrollerar du att App Service-nivån är Basic B1 eller högre. App Service kräver en Basic B1 eller högre tjänstnivå för att använda anpassade domäner.
  7. När Azure har skapat App Service öppnar du appens Configuration och lägger till en ny programinställning som anger certifikatets tumavtryck som registrerats tidigare. Appinställningsnyckeln är WEBSITE_LOAD_CERTIFICATES. Avgränsa certifikatets tumavtryck i appinställningsvärdet med ett kommatecken, som följande exempel visar:

    • Nyckel: WEBSITE_LOAD_CERTIFICATES
    • Värde: 57443A552A46DB...D55E28D412B943565,29F43A772CB6AF...1D04F0C67F85FB0B1

    I Azure-portalen är det en tvåstegsprocess att spara appinställningar: Spara inställningen WEBSITE_LOAD_CERTIFICATES nyckelvärde och välj sedan knappen Spara överst på bladet.

  8. Välj appens TLS/SSL-inställningar. Välj Privata nyckelcertifikat (.pfx). Använd processen Importera nyckelvalvscertifikat. Använd processen två gånger för att importera både webbplatsens certifikat för HTTPS-kommunikation och webbplatsens självsignerade signeringscertifikat för Identity Server-token.

  9. Gå till bladet Anpassade domäner. På domänregistratorns webbplats använder du IP-adress och anpassat domänverifierings-ID för att konfigurera domänen. En typisk domänkonfiguration omfattar:

    • En A Record med en värd av @ och IP-adressvärdet från Azure-portalen.
    • En TXT-post med en värd av asuid och värdet av verifierings-ID:t som genereras av Azure och tillhandahålls av Azure-portalen.

    Se till att du sparar ändringarna på domänregistratorns webbplats korrekt. Vissa registratorwebbplatser kräver en tvåstegsprocess för att spara domänposter: En eller flera poster sparas individuellt följt av uppdatering av domänens registrering med en separat knapp.

  10. Gå tillbaka till bladet anpassade domäner i Azure-portalen. Välj Lägg till anpassad domän. Välj alternativet A Record. Ange domänen och välj Verifiera. Om domänposterna är korrekta och har spridits över internet kan du i portalen välja knappen Lägg till anpassad domän.

    Det kan ta några dagar innan domänregistreringsändringar sprids över Internet-domännamnsservrar (DNS) när de har bearbetats av domänregistratorn. Om domänposter inte uppdateras inom tre arbetsdagar bekräftar du att posterna har angetts korrekt hos domänregistratorn och kontaktar kundsupporten.

  11. På bladet Anpassade domäner markeras SSL STATE för domänen Not Secure. Välj länken Lägg till bindning. Välj webbplatsens HTTPS-certifikat från nyckelvalvet för den anpassade domänbindningen.

  12. I Visual Studio öppnar du Server-projektets appinställningsfil (appsettings.json eller appsettings.Production.json). I konfigurationen Identity Server lägger du till följande Key avsnitt. Ange det självsignerade certifikatet Ämne för Name-nyckeln. I följande exempel är certifikatets vanliga namn som tilldelats i nyckelvalvet IdentityServerSigning, vilket ger ett SubjectCN=IdentityServerSigning:

    "IdentityServer": {
    
      ...
    
      "Key": {
        "Type": "Store",
        "StoreName": "My",
        "StoreLocation": "CurrentUser",
        "Name": "CN=IdentityServerSigning"
      }
    },
    
  13. I Visual Studio skapar du en publiceringsprofil för Azure App Service projekt Server. I menyraden, välj: Build>Publish>New>Azure>Azure App Service (Windows eller Linux). När Visual Studio är anslutet till en Azure-prenumeration kan du ställa in Azure-resursernas View efter Resurstyp. Navigera i listan Web App för att hitta App Service för appen och välj den. Välj Slutför.

  14. När Visual Studio återgår till fönstret Publicera identifieras beroenden för nyckelvalvet och SQL Server-databastjänsten automatiskt.

    Inga konfigurationsändringar av standardinställningarna krävs för key vault-tjänsten.

    I testsyfte kan en apps lokala SQLite- databas, som konfigureras av Blazor-mallen, distribueras med appen utan ytterligare konfiguration. Att konfigurera en annan databas för Identity Server i produktion ligger utanför omfånget för den här artikeln. Mer information finns i databasresurserna i följande dokumentationsuppsättningar:

  15. Välj länken Redigera under namnet på distributionsprofilen överst på fönstret. Ändra mål-URL:en till webbplatsens anpassade domän-URL (till exempel https://www.contoso.com). Spara inställningarna.

  16. Publicera appen. Visual Studio öppnar ett webbläsarfönster och begär webbplatsen på sin anpassade domän.

Azure-dokumentationen innehåller ytterligare information om hur du använder Azure-tjänster och anpassade domäner med TLS-bindning i App Service, inklusive information om hur du använder CNAME-poster i stället för A-poster. Mer information finns i följande resurser:

Vi rekommenderar att du använder ett nytt webbläsarfönster för privat läge (till exempel Microsoft Edge InPrivate-läge eller Google Chrome Incognito-läge) för varje apptestkörning efter en ändring av appen, appkonfigurationen eller Azure-tjänsterna i Azure-portalen. Kvardröjande cookies från en tidigare testkörning kan leda till misslyckad autentisering eller auktorisering när webbplatsen testas, även när webbplatsens konfiguration är korrekt. Mer information om hur du konfigurerar Visual Studio för att öppna ett nytt privat webbläsarfönster för varje testkörning finns i avsnittet Cookies och webbplatsdata.

När App Service-konfigurationen ändras i Azure-portalen börjar uppdateringarna vanligtvis gälla snabbt men är inte omedelbara. Ibland måste du vänta en kort stund innan en App Service startas om för att en konfigurationsändring ska börja gälla.

Om du felsöker ett problem med inläsning av ett Identity Server-nyckelsigneringscertifikat, kör följande kommando i Azure-portalen Kudu PowerShell-kommandogränssnittet. Kommandot innehåller en lista över certifikat som appen kan komma åt från CurrentUser>My certifikatarkivet. Utdata innehåller certifikatsämnen och tumavtryck som är användbara vid felsökning av en app.

Get-ChildItem -path Cert:\CurrentUser\My -Recurse | Format-List DnsNameList, Subject, Thumbprint, EnhancedKeyUsageList

Felsöka

Skogsavverkning

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.

    Konfigurationsavsnitt i den här artikelns vägledning visar exempel på rätt konfiguration. Kontrollera noggrant varje avsnitt i artikeln som letar efter felkonfiguration av appar och IP-adresser.

    Om konfigurationen verkar vara korrekt:

    • Analysera applikationsloggar.

    • 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:

    • För versioner av Blazor där en JSON-webbtoken (JWT) används avkodar du innehållet i token som används för att autentisera en klient eller komma åt ett webb-API för servrar, beroende på var problemet uppstår. Mer information finns i Granska innehållet i en JSON-webbtoken (JWT).

    Dokumentationsteamet svarar på dokumentfeedback och buggar i artiklar (öppna ett ärende från Den här sidan feedbacksektionen) men kan inte erbjuda 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 ramverksbuggar, öppna ett ärende med ASP.NET Core-produktenheten . Öppna inte ett ärende med produktteamet förrän du noggrant har undersökt orsaken till ett problem och ingen lösning kan hittas på egen hand eller med hjälp av gemenskapen 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 vid 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 hjälp av från Visual Studio-knappen Kör.
    • Välj knappen Lägg till.
    • Ange sökvägen till webbläsaren i fältet Program. Typiska installationssökvägar för Windows 10 inkluderar följande. 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 användarvänligt namn i fältet Eget 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 orsaka att en app slutar fungera när större uppgraderingar görs. 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.

Not

Användning av paketversioner som inte är kompatibla med appens målramverk stöds inte. För att få information om ett paket, använd NuGet-galleriet.

Kör Server-appen

När du testar och felsöker en värdbaserad Blazor WebAssemblylösningkontrollerar du att du kör appen från Server-projektet.

Inspektera användaren

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

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

Granska innehållet i en JSON-webbtoken (JWT)

Om du vill avkoda en JSON-webbtoken (JWT) använder du Microsofts jwt.ms-verktyg. Värden i användargränssnittet lämnar aldrig webbläsaren.

Exempelkodad JWT (förkortad för visning):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Exempel på JWT-avkodad av verktyget för en app som autentiserar mot Azure AAD B2C:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
  "sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
  "aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

Ytterligare resurser