Zabezpečení hostované aplikace ASP.NET Core Blazor WebAssembly pomocí Identity serveru

Tento článek vysvětluje, jak vytvořit hostované Blazor WebAssembly řešení , které k ověřování uživatelů a volání rozhraní API používá Duende Identity Server .

Důležité

Duende Software může vyžadovat, abyste zaplatili licenční poplatek za produkční využití serveru Duende Identity Server. Další informace najdete v tématu Migrace z ASP.NET Core 5.0 na verzi 6.0.

Poznámka:

Pokud chcete nakonfigurovat samostatnou nebo hostované Blazor WebAssembly aplikaci tak, aby používala existující externí Identity instanci serveru, postupujte podle pokynů v tématu Zabezpečení samostatné aplikace ASP.NET Core Blazor WebAssembly pomocí knihovny ověřování.

Další pokrytí scénáře zabezpečení po přečtení tohoto článku najdete v tématu ASP.NET Core Blazor WebAssembly další scénáře zabezpečení.

Názorný postup

Pododdíly návodu vysvětlují, jak:

  • Blazor Vytvoření aplikace
  • Spustit aplikaci

Vytvoření Blazor aplikace

Vytvoření nového Blazor WebAssembly projektu pomocí mechanismu ověřování:

  1. Vytvoření nového projektu

  2. Blazor WebAssembly Zvolte šablonu aplikace. Vyberte Další.

  3. Zadejte název projektu bez použití pomlček. Ověřte správnost umístění . Vyberte Další.

    Nepoužívejte pomlčky (-) v názvu projektu, které přeruší vytvoření identifikátoru aplikace OIDC. Logika v Blazor WebAssembly šabloně projektu používá název projektu pro identifikátor aplikace OIDC v konfiguraci řešení a pomlčky nejsou povoleny v identifikátoru aplikace OIDC. Argumenty typu Pascal () nebo podtržítka (BlazorSampleBlazor_Sample) jsou přijatelné alternativy.

  4. V dialogovém okně Další informace vyberte jako typ ověřování jednotlivé účty, které budou uživatele ukládat v aplikaci pomocí systému ASP.NET CoreIdentity.

  5. Zaškrtněte políčko ASP.NET Hostované jádro.

  6. Vyberte tlačítko Vytvořit a vytvořte aplikaci.

Spustit aplikaci

Spusťte aplikaci z Server projektu. Při použití sady Visual Studio:

  • Vyberte šipku rozevíracího seznamu vedle tlačítka Spustit . V rozevíracím seznamu otevřete Konfigurovat projekty po spuštění. Vyberte možnost Jeden spouštěný projekt. Potvrďte nebo změňte projekt pro projekt po spuštění na Server projekt.

  • Než aplikaci spustíte, ověřte, že Server je projekt zvýrazněný v Průzkumník řešení:

    • Vyberte tlačítko Run (Spustit).
    • V nabídce použijte ladění spustit ladění.>
    • Stiskněte klávesu F5.
  • V příkazovém prostředí přejděte do Server složky projektu řešení. Spusťte příkaz dotnet run.

Části řešení

Tato část popisuje části řešení vygenerované ze Blazor WebAssembly šablony projektu a popisuje způsob konfigurace řešení Client a Server projektů pro referenci. Pokud jste aplikaci vytvořili pomocí pokynů v části Návod , není v této části potřeba postupovat podle konkrétních pokynů. Pokyny v této části jsou užitečné pro aktualizaci aplikace pro ověřování a autorizaci uživatelů. Alternativním přístupem k aktualizaci aplikace je ale vytvoření nové aplikace z pokynů v části Návod a přesun komponent, tříd a prostředků aplikace do nové aplikace.

Server app services

Tato část se týká aplikace řešení Server .

Zaregistrují se následující služby.

  • V souboru Program:

    • Entity Framework Core a 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 s další AddApiAuthorization pomocnou metodou, která nastavuje výchozí konvence jádra ASP.NET nad Identity serverem:

      builder.Services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Ověřování pomocí další AddIdentityServerJwt pomocné metody, která nakonfiguruje aplikaci tak, aby ověřila tokeny JWT vytvořené serverem Identity :

      builder.Services.AddAuthentication()
          .AddIdentityServerJwt();
      
  • In Startup.ConfigureServices of Startup.cs:

    • Entity Framework Core a ASP.NET Core Identity:

      services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite(
              Configuration.GetConnectionString("DefaultConnection")));
      
      services.AddDefaultIdentity<ApplicationUser>(options => 
              options.SignIn.RequireConfirmedAccount = true)
          .AddEntityFrameworkStores<ApplicationDbContext>();
      
    • Identity Server s další AddApiAuthorization pomocnou metodou, která nastavuje výchozí konvence jádra ASP.NET nad Identity serverem:

      services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Ověřování pomocí další AddIdentityServerJwt pomocné metody, která nakonfiguruje aplikaci tak, aby ověřila tokeny JWT vytvořené serverem Identity :

      services.AddAuthentication()
          .AddIdentityServerJwt();
      

Poznámka:

Při registraci jednoho schématu ověřování se schéma ověřování automaticky použije jako výchozí schéma aplikace a není nutné schéma uvést do AddAuthentication nebo přes AuthenticationOptions. Další informace najdete v tématu Přehled ASP.NET základního ověřování a oznámení ASP.NET Core (aspnet/Oznámení č. 490).

  • V souboru Program:
  • In Startup.Configure of Startup.cs:
  • Middleware Identity serveru zveřejňuje koncové body OpenID Připojení (OIDC):

    app.UseIdentityServer();
    
  • Ověřovací middleware zodpovídá za ověřování přihlašovacích údajů žádosti a nastavení uživatele v kontextu požadavku:

    app.UseAuthentication();
    
  • Middleware autorizace umožňuje možnosti autorizace:

    app.UseAuthorization();
    

Autorizace rozhraní API

Tato část se týká aplikace řešení Server .

Pomocná AddApiAuthorization metoda konfiguruje Identity Server pro scénáře ASP.NET Core. Identity Server je výkonná a rozšiřitelná architektura pro zpracování problémů se zabezpečením aplikací. Identity Server zveřejňuje zbytečné složitosti pro nejběžnější scénáře. V důsledku toho je k dispozici sada konvencí a možností konfigurace, kterou považujeme za dobrý výchozí bod. Jakmile se vaše ověřování změní, je k dispozici plný výkon Identity serveru, který přizpůsobí ověřování tak, aby vyhovoval požadavkům aplikace.

Přidání obslužné rutiny ověřování pro rozhraní API, které spoluexistuje se serverem Identity

Tato část se týká aplikace řešení Server .

Pomocná AddIdentityServerJwt metoda nakonfiguruje schéma zásad pro aplikaci jako výchozí obslužnou rutinu ověřování. Zásada je nakonfigurovaná tak, aby umožňovala Identity zpracovávat všechny požadavky směrované na jakoukoli dílčí cestu v prostoru adresy URL v Identity části /Identity. Zpracovává JwtBearerHandler všechny ostatní požadavky. Kromě toho tato metoda:

  • Zaregistruje prostředek rozhraní API na Identity serveru s výchozím oborem {PROJECT NAME}API, kde {PROJECT NAME} zástupný symbol je název projektu při vytváření aplikace.
  • Nakonfiguruje middleware nosných tokenů JWT tak, aby ověřil tokeny vydané serverem Identity pro aplikaci.

Kontroler předpovědi počasí

Tato část se týká aplikace řešení Server .

WeatherForecastController V (Controllers/WeatherForecastController.cs), [Authorize] atribut je použit pro třídu. Atribut označuje, že uživatel musí být autorizovaný na základě výchozí zásady pro přístup k prostředku. Výchozí zásady autorizace jsou nakonfigurovány tak, aby používaly výchozí schéma ověřování, které je nastaveno AddIdentityServerJwt. Pomocná metoda konfiguruje JwtBearerHandler jako výchozí obslužnou rutinu pro požadavky na aplikaci.

Kontext databáze aplikace

Tato část se týká aplikace řešení Server .

ApplicationDbContext V části (Data/ApplicationDbContext.cs) DbContext se rozšiřuje ApiAuthorizationDbContext<TUser> o zahrnutí schématu pro Identity server. ApiAuthorizationDbContext<TUser> je odvozen z IdentityDbContext.

Chcete-li získat úplnou kontrolu nad schématem databáze, dědí z jedné z dostupných IdentityDbContext tříd a nakonfigurujte kontext tak, aby zahrnoval Identity schéma voláním builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value) v OnModelCreating metodě.

Kontroler konfigurace OIDC

Tato část se týká aplikace řešení Server .

V (OidcConfigurationControllerControllers/OidcConfigurationController.cs) je koncový bod klienta zřízený tak, aby sloužil parametrům OIDC.

Nastavení aplikace

Tato část se týká aplikace řešení Server .

V souboru nastavení aplikace (appsettings.json) v kořenovém adresáři IdentityServer projektu popisuje část seznam nakonfigurovaných klientů. V následujícím příkladu je jeden klient. Název klienta odpovídá Client názvu sestavení aplikace a mapuje se konvencí na parametr OAuth ClientId . Profil označuje typ aplikace, který se konfiguruje. Profil se používá interně ke konvencím jednotek, které zjednodušují proces konfigurace serveru.

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

Zástupný symbol {ASSEMBLY NAME} je Client název sestavení aplikace (například BlazorSample.Client).

Ověřovací balíček

Tato část se týká aplikace řešení Client .

Když je aplikace vytvořená tak, aby používala jednotlivé uživatelské účty (Individual), aplikace automaticky obdrží odkaz na Microsoft.AspNetCore.Components.WebAssembly.Authentication balíček. Balíček poskytuje sadu primitiv, které aplikaci pomáhají ověřovat uživatele a získávat tokeny pro volání chráněných rozhraní API.

Pokud do aplikace přidáváte ověřování, přidejte balíček Microsoft.AspNetCore.Components.WebAssembly.Authentication do aplikace ručně.

Poznámka:

Pokyny k přidávání balíčků do aplikací .NET najdete v článcích v části Instalace a správa balíčků na webu Pracovní postup používání balíčků (dokumentace k NuGetu). Ověřte správné verze balíčků na NuGet.org.

Konfigurace HttpClient

Tato část se týká aplikace řešení Client .

Program V souboru je pojmenovaný HttpClient nakonfigurovaný tak, aby při provádění požadavků na serverové rozhraní API obsahoval HttpClient přístupové tokeny, které zahrnují přístupové tokeny. Ve výchozím nastavení při vytváření řešení je {PROJECT NAME}.ServerAPInázev HttpClient , kde {PROJECT NAME} zástupný symbol je název projektu.

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

Zástupný symbol {PROJECT NAME} je název projektu při vytváření řešení. Například zadáním názvu BlazorSample projektu vznikne název HttpClient .BlazorSample.ServerAPI

Poznámka:

Pokud konfigurujete Blazor WebAssembly aplikaci tak, aby používala existující Identity instanci serveru, která není součástí hostovaného Blazor řešení, změňte HttpClient základní registraci adresy z IWebAssemblyHostEnvironment.BaseAddress (builder.HostEnvironment.BaseAddress) na adresu URL koncového bodu autorizace rozhraní API serverové aplikace.

Podpora autorizace rozhraní API

Tato část se týká aplikace řešení Client .

Podpora ověřování uživatelů je zapojena do kontejneru služby metodou rozšíření poskytovanou uvnitř Microsoft.AspNetCore.Components.WebAssembly.Authentication balíčku. Tato metoda nastaví služby vyžadované aplikací pro interakci s existujícím systémem autorizace.

builder.Services.AddApiAuthorization();

Ve výchozím nastavení se konfigurace aplikace načítá podle konvence z _configuration/{client-id}. Podle konvence je ID klienta nastavené na název sestavení aplikace. Tuto adresu URL je možné změnit tak, aby odkazovat na samostatný koncový bod voláním přetížení s možnostmi.

Soubor Imports

Tato část se týká aplikace řešení Client .

Obor Microsoft.AspNetCore.Components.Authorization názvů je dostupný v celé aplikaci prostřednictvím _Imports.razor souboru:

@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 Stránka

Tato část se týká aplikace řešení Client .

Stránka Index (wwwroot/index.html) obsahuje skript, který definuje v JavaScriptu AuthenticationService . AuthenticationService zpracovává podrobnosti nízké úrovně protokolu OIDC. Aplikace interně volá metody definované ve skriptu k provádění ověřovacích operací.

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

App Komponenty

Tato část se týká aplikace řešení Client .

Komponenta App (App.razor) se podobá komponentě App nalezené v Blazor Server aplikacích:

  • Komponenta CascadingAuthenticationState spravuje vystavení AuthenticationState zbytku aplikace.
  • Komponenta AuthorizeRouteView zajišťuje, že aktuální uživatel má oprávnění pro přístup k dané stránce nebo že komponentu RedirectToLogin jinak vykresluje.
  • Komponenta RedirectToLogin spravuje přesměrování neoprávněných uživatelů na přihlašovací stránku.

Vzhledem ke změnám v rozhraní napříč verzemi ASP.NET Core Razor se v této části nezobrazují značky komponenty App (App.razor). Pokud chcete zkontrolovat kód komponenty pro danou verzi, použijte některý z následujících přístupů:

  • Vytvořte aplikaci zřízenou pro ověřování z výchozí Blazor WebAssembly šablony projektu pro verzi ASP.NET Core, kterou chcete použít. Zkontrolujte komponentu App (App.razor) ve vygenerované aplikaci.

  • Zkontrolujte komponentu (App.razor) v referenčním App zdroji. Vyberte verzi ze selektoru větve a vyhledejte komponentu ve ProjectTemplates složce úložiště, protože se v průběhu let přesunula.

    Poznámka:

    Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

RedirectToLogin Komponenty

Tato část se týká aplikace řešení Client .

Komponenta RedirectToLogin (RedirectToLogin.razor):

  • Spravuje přesměrování neoprávněných uživatelů na přihlašovací stránku.
  • Aktuální adresa URL, ke které se uživatel pokouší získat přístup, je udržována tak, aby se v případě úspěšného ověření vrátila na tuto stránku:
    • Stav historie navigace v ASP.NET Core v .NET 7 nebo novějším
    • Řetězec dotazu v ASP.NET Core v .NET 6 nebo starší.

Zkontrolujte komponentu v referenčním RedirectToLogin zdroji. Umístění komponenty se v průběhu času změnilo, proto k vyhledání komponenty použijte vyhledávací nástroje GitHubu.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

LoginDisplay Komponenty

Tato část se týká aplikace řešení Client .

Komponenta LoginDisplay (LoginDisplay.razor) se vykreslí MainLayout v komponentě (MainLayout.razor) a spravuje následující chování:

  • Pro ověřené uživatele:
    • Zobrazí aktuální uživatelské jméno.
    • Nabízí odkaz na stránku profilu uživatele v ASP.NET Core Identity.
    • Nabízí tlačítko pro odhlášení z aplikace.
  • Anonymní uživatelé:
    • Nabízí možnost registrace.
    • Nabízí možnost přihlášení.

Vzhledem ke změnám v rozhraní napříč verzemi ASP.NET Core Razor se v této části nezobrazují značky komponenty LoginDisplay . Pokud chcete zkontrolovat kód komponenty pro danou verzi, použijte některý z následujících přístupů:

  • Vytvořte aplikaci zřízenou pro ověřování z výchozí Blazor WebAssembly šablony projektu pro verzi ASP.NET Core, kterou chcete použít. Zkontrolujte komponentu LoginDisplay ve vygenerované aplikaci.

  • Zkontrolujte komponentu v referenčním LoginDisplay zdroji. Umístění komponenty se v průběhu času změnilo, proto k vyhledání komponenty použijte vyhledávací nástroje GitHubu. Použije se šablonovaný obsah, Hosted který true se rovná.

    Poznámka:

    Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Authentication Komponenty

Tato část se týká aplikace řešení Client .

Stránka vytvořená komponentou Authentication (Pages/Authentication.razor) definuje trasy potřebné pro zpracování různých fází ověřování.

Komponenta RemoteAuthenticatorView :

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

<RemoteAuthenticatorView Action="Action" />

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

Poznámka:

Statické analýzy stavu null s možnou hodnotou null (NRT) a kompilátoru .NET se podporují v ASP.NET Core v .NET 6 nebo novějším. Před vydáním ASP.NET Core v .NET 6 string se typ zobrazí bez označení typu null (?).

FetchData Komponenty

Tato část se týká aplikace řešení Client .

Komponenta FetchData ukazuje, jak:

  • Zřízení přístupového tokenu
  • Přístupový token použijte k volání chráněného rozhraní API prostředků v aplikaci Server .

Direktiva @attribute [Authorize]Blazor WebAssembly označuje autorizační systém, že uživatel musí být autorizovaný, aby mohl tuto komponentu navštívit. Přítomnost atributu Client v aplikaci nezabrání volání rozhraní API na serveru bez správných přihlašovacích údajů. Aplikace Server musí také používat [Authorize] příslušné koncové body, aby je správně chránila.

IAccessTokenProvider.RequestAccessToken postará se o vyžádání přístupového tokenu, který je možné přidat do požadavku pro volání rozhraní API. Pokud je token uložený v mezipaměti nebo služba dokáže zřídit nový přístupový token bez zásahu uživatele, žádost o token proběhne úspěšně. V opačném případě požadavek tokenu selže s chybou AccessTokenNotAvailableException, která je zachycena try-catch v příkazu.

Aby bylo možné získat skutečný token, který se má zahrnout do požadavku, musí aplikace zkontrolovat, že požadavek byl úspěšný voláním tokenResult.TryGetToken(out var token).

Pokud byl požadavek úspěšný, proměnná tokenu se naplní přístupovým tokenem. AccessToken.Value Vlastnost tokenu zveřejňuje řetězec literálu, který se má zahrnout do hlavičky Authorization požadavku.

Pokud požadavek selhal, protože se token nepodařilo zřídit bez zásahu uživatele:

  • ASP.NET Core v .NET 7 nebo novějším: Aplikace přejde k AccessTokenResult.InteractiveRequestUrl použití dané AccessTokenResult.InteractionOptions aplikace, aby umožňovala aktualizaci přístupového tokenu.
  • ASP.NET Core v .NET 6 nebo starší: Výsledek tokenu obsahuje adresu URL přesměrování. Přechod na tuto adresu URL přenese uživatele na přihlašovací stránku a po úspěšném ověření se vrátí na aktuální stránku.
@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();
        }
    }
}

Aplikace Azure Service v Linuxu

Explicitně zadejte vystavitele při nasazování do služby Aplikace Azure Service v Linuxu. Další informace najdete v tématu Použití Identity k zabezpečení back-endu webového rozhraní API pro služby SPA.

Název a deklarace identity role s autorizací rozhraní API

Vlastní uživatelská továrna

Client V aplikaci vytvořte vlastní objekt pro vytváření uživatelů. Identity Server odesílá několik rolí jako pole JSON v jedné role deklaraci identity. Jedna role se odešle jako řetězcová hodnota deklarace identity. Objekt pro vytváření vytvoří jednotlivou role deklaraci identity pro každou roli uživatele.

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
    : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
    public CustomUserFactory(IAccessTokenProviderAccessor accessor)
        : base(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;
    }
}
using System.Linq;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;

public class CustomUserFactory
    : AccountClaimsPrincipalFactory<RemoteUserAccount>
{
    public CustomUserFactory(IAccessTokenProviderAccessor accessor)
        : base(accessor)
    {
    }

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        RemoteUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        if (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 (rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            identity.AddClaim(new Claim(options.RoleClaim, role.GetString()));
                        }
                    }
                    else
                    {
                        identity.AddClaim(new Claim(options.RoleClaim, roles.GetString()));
                    }
                }
            }
        }

        return user;
    }
}

Client V aplikaci zaregistrujte továrnu Program v souboru:

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

Server V aplikaci zavolejte AddRolesIdentity tvůrce, který přidává služby související s rolemi.

V souboru Program:

using Microsoft.AspNetCore.Identity;

...

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

V Startup.cs:

using Microsoft.AspNetCore.Identity;

...

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

Konfigurace Identity serveru

Použijte jeden z následujících přístupů:

Možnosti autorizace rozhraní API

Server V aplikaci:

  • Nakonfigurujte Identity server tak, aby vložil name deklarace role identity do tokenu ID a přístupového tokenu.
  • Zabrání výchozímu mapování rolí v obslužné rutině tokenu JWT.

V souboru 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");

V 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");

Profilová služba

Server V aplikaci vytvořte implementaciProfileService.

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;
    }
}
using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using System.Threading.Tasks;

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

Server V aplikaci zaregistrujte službu profilu v Program souboru:

using Duende.IdentityServer.Services;

...

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

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Server V aplikaci zaregistrujte službu profilu v Startup.ConfigureServices :Startup.cs

using IdentityServer4.Services;

...

services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Použití autorizačních mechanismů

Client V aplikaci jsou přístupy k autorizaci komponent v tuto chvíli funkční. Jakýkoli z mechanismů autorizace v komponentách může použít roli k autorizaci uživatele:

User.Identity.Name aplikace se vyplní Client uživatelským jménem uživatele, což je obvykle jeho přihlašovací e-mailová adresa.

UserManager a SignInManager

Nastavte typ deklarace identity identifikátoru uživatele, když aplikace serveru vyžaduje:

V Program.cs případě ASP.NET Core v .NET 6 nebo novějším:

using System.Security.Claims;

...

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

Ve Startup.ConfigureServices verzích ASP.NET Core starších než 6.0:

using System.Security.Claims;

...

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

Následující WeatherForecastController protokoluje UserName , kdy Get je volána metoda.

Poznámka:

Následující příklad používá obor názvů s oborem souborů, což je funkce C# 10 nebo novější (.NET 6 nebo novější).

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 : ControllerBase
{
    private readonly UserManager<ApplicationUser> userManager;

    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", 
        "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, 
        UserManager<ApplicationUser> userManager)
    {
        this.logger = logger;
        this.userManager = userManager;
    }

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

V předchozím příkladu:

  • Obor Server názvů projektu je BlazorSample.Server.
  • Obor Shared názvů projektu je BlazorSample.Shared.

Hostování ve službě Aplikace Azure Service s vlastní doménou a certifikátem

Následující doprovodné materiály vysvětlují:

  • Postup nasazení hostované Blazor WebAssembly aplikace se serverem Identity do služby Aplikace Azure Service s vlastní doménou
  • Vytvoření a použití certifikátu TLS pro komunikaci protokolu HTTPS s prohlížeči I když se pokyny zaměřují na používání certifikátu s vlastní doménou, pokyny platí stejně pro použití výchozí domény Aplikace Azure s, například contoso.azurewebsites.net.

Pro tento scénář hostování nepoužívejtestejný certifikát proIdentitypodpisový klíč tokenu serveru a zabezpečenou komunikaci HTTPS webu s prohlížeči:

  • Použití různých certifikátů pro tyto dva požadavky je dobrým postupem zabezpečení, protože izoluje privátní klíče pro každý účel.
  • Certifikáty TLS pro komunikaci s prohlížeči se spravují nezávisle, aniž by to ovlivnilo Identity podepisování tokenů serveru.
  • Když Azure Key Vault dodává certifikát aplikaci App Service pro vlastní vazbu domény, Identity server nemůže získat stejný certifikát ze služby Azure Key Vault pro podepisování tokenů. Přestože je možné nakonfigurovat Identity server tak, aby používal stejný certifikát TLS z fyzické cesty, umístění certifikátů zabezpečení do správy zdrojového kódu je špatný postup a ve většině scénářů byste se měli vyhnout.

V následujících doprovodných materiálech se certifikát podepsaný svým držitelem vytvoří ve službě Azure Key Vault výhradně pro Identity podepisování tokenů serveru. Konfigurace Identity serveru používá certifikát trezoru klíčů prostřednictvím úložiště certifikátů aplikace>CurrentUserMy. Další certifikáty používané pro provoz HTTPS s vlastními doménami se vytvářejí a konfigurují odděleně od podpisového Identity certifikátu serveru.

Konfigurace aplikace, služby Aplikace Azure a služby Azure Key Vault pro hostování s vlastní doménou a HTTPS:

  1. Vytvořte plán služby App Service s úrovní Basic B1 plánu nebo vyšší. App Service vyžaduje Basic B1 nebo vyšší úroveň služby pro použití vlastních domén.

  2. Vytvořte certifikát PFX pro zabezpečenou komunikaci prohlížeče (protokol HTTPS) webu s běžným názvem plně kvalifikovaného názvu domény (FQDN), který řídí vaše organizace (například www.contoso.com). Vytvořte certifikát pomocí:

    • Použití klíče
      • Ověření digitálního podpisu (digitalSignature)
      • Šifrování klíče (keyEncipherment)
    • Rozšířené nebo rozšířené použití klíče
      • Ověřování klienta (1.3.6.1.5.5.7.3.2)
      • Ověřování serveru (1.3.6.1.5.5.7.3.1)

    K vytvoření certifikátu použijte jeden z následujících přístupů nebo jakýkoli jiný vhodný nástroj nebo online službu:

    Poznamenejte si heslo, které se použije později k importu certifikátu do služby Azure Key Vault.

    Další informace o certifikátech služby Azure Key Vault najdete v tématu Azure Key Vault: Certifikáty.

  3. Vytvořte novou službu Azure Key Vault nebo použijte existující trezor klíčů ve vašem předplatném Azure.

  4. V oblasti Certifikáty trezoru klíčů naimportujte certifikát lokality PFX. Poznamenejte si kryptografický otisk certifikátu, který se použije v konfiguraci aplikace později.

  5. Ve službě Azure Key Vault vygenerujte nový certifikát podepsaný svým držitelem pro Identity podepisování tokenů serveru. Dejte certifikátu název certifikátu a předmět. Předmět je určen jako CN={COMMON NAME}, kde {COMMON NAME} zástupný symbol je běžný název certifikátu. Běžný název může být libovolný alfanumerický řetězec. Jedná se například CN=IdentityServerSigning o platný předmět certifikátu. V části Konfigurace rozšířených zásad> vystavování použijte výchozí nastavení. Poznamenejte si kryptografický otisk certifikátu, který se použije v konfiguraci aplikace později.

  6. Na webu Azure Portal přejděte na Aplikace Azure Service a vytvořte novou službu App Service s následující konfigurací:

    • Publikování je nastaveno na Codehodnotu .
    • Zásobník modulu runtime nastavený na modul runtime aplikace
    • V případě skladové položky a velikosti ověřte, že je Basic B1 úroveň služby App Service nebo vyšší. App Service vyžaduje Basic B1 nebo vyšší úroveň služby pro použití vlastních domén.
  7. Jakmile Azure vytvoří službu App Service, otevřete konfiguraci aplikace a přidejte nové nastavení aplikace určující kryptografické otisky certifikátu zaznamenané dříve. Klíč nastavení aplikace je WEBSITE_LOAD_CERTIFICATES. Kryptografické otisky certifikátu v hodnotě nastavení aplikace oddělte čárkou, jak ukazuje následující příklad:

    • Klíč: WEBSITE_LOAD_CERTIFICATES
    • Hodnota: 57443A552A46DB...D55E28D412B943565,29F43A772CB6AF...1D04F0C67F85FB0B1

    Uložení nastavení aplikace na webu Azure Portal je dvoustupňový proces: Uložte WEBSITE_LOAD_CERTIFICATES nastavení klíč-hodnota a pak vyberte tlačítko Uložit v horní části okna.

  8. Vyberte nastavení PROTOKOLU TLS/SSL aplikace. Vyberte certifikáty privátního klíče (.pfx). Použijte proces importu certifikátu služby Key Vault. Tento postup použijte dvakrát k importu certifikátu webu pro komunikaci HTTPS i podpisového certifikátu tokenu serveru podepsaného svým držitelem Identity .

  9. Přejděte do okna Vlastní domény . Na webu doménového registrátora nakonfigurujte doménu pomocí IP adresy a ID ověření vlastní domény. Typická konfigurace domény zahrnuje:

    • Záznam A s hostitelem@ a hodnotou IP adresy z webu Azure Portal.
    • Txt Record with a Host of asuid and the value of the verification ID generated by Azure and provided by the Azure Portal.

    Ujistěte se, že změny uložíte na webu doménového registrátora správně. Některé weby registrátora vyžadují, aby se záznamy domény ukládaly dvěma kroky: Jeden nebo více záznamů se ukládá jednotlivě a pak aktualizuje registraci domény samostatným tlačítkem.

  10. Vraťte se do okna Vlastní domény na webu Azure Portal. Vyberte Přidat vlastní doménu. Vyberte možnost Záznam A. Zadejte doménu a vyberte Ověřit. Pokud jsou záznamy domény správné a šíří se přes internet, portál umožňuje vybrat tlačítko Přidat vlastní doménu .

    Může trvat několik dní, než se změny registrace domény rozšíří mezi internetové názvové servery domény (DNS) po jejich zpracování vaším doménovým registrátorem. Pokud se záznamy domény neaktualizují do tří pracovních dnů, ověřte, že jsou záznamy správně nastavené u doménového registrátora, a obraťte se na zákaznickou podporu.

  11. V okně Vlastní domény je označen Not Securestav SSL pro doménu . Vyberte odkaz Přidat vazbu. Vyberte certifikát HTTPS lokality z trezoru klíčů pro vlastní vazbu domény.

  12. V sadě Visual Studio otevřete soubor nastavení aplikace projektu serveru (appsettings.json nebo appsettings.Production.json). Identity V konfiguraci serveru přidejte následující Key část. Zadejte předmět certifikátu podepsaného Name svým držitelem pro klíč. V následujícím příkladu je běžný název certifikátu přiřazený v trezoru IdentityServerSigningklíčů , který poskytuje předmětCN=IdentityServerSigning:

    "IdentityServer": {
    
      ...
    
      "Key": {
        "Type": "Store",
        "StoreName": "My",
        "StoreLocation": "CurrentUser",
        "Name": "CN=IdentityServerSigning"
      }
    },
    
  13. V sadě Visual Studio vytvořte profil publikování služby Aplikace Azure pro projekt serveru. Na řádku nabídek vyberte: Build>Publish>New>Azure> Aplikace Azure Service (Windows nebo Linux). Když je Visual Studio připojené k předplatnému Azure, můžete nastavit zobrazení prostředků Azure podle typu prostředku. V seznamu webových aplikací vyhledejte App Service pro aplikaci a vyberte ji. Vyberte Dokončit.

  14. Když se Visual Studio vrátí do okna Publikovat , automaticky se zjistí závislosti trezoru klíčů a databázové služby SQL Serveru.

    Pro službu trezoru klíčů se nevyžadují žádné změny konfigurace výchozích nastavení.

    Pro účely testování je možné nasadit místní databázi SQLite aplikace, která je ve výchozím nastavení Blazor nakonfigurovaná šablonou, s aplikací bez další konfigurace. Konfigurace jiné databáze pro Identity server v produkčním prostředí je nad rámec tohoto článku. Další informace najdete v databázových prostředcích v následujících sadách dokumentace:

  15. V horní části okna vyberte odkaz Upravit pod názvem profilu nasazení. Změňte cílovou adresu URL na adresu URL vlastní domény webu (například https://www.contoso.com). Uložte nastavení.

  16. Umožňuje publikovat aplikaci. Visual Studio otevře okno prohlížeče a požádá web o vlastní doménu.

Dokumentace k Azure obsahuje další podrobnosti o používání služeb Azure a vlastních domén s vazbou TLS ve službě App Service, včetně informací o použití záznamů CNAME místo záznamů A. Další informace naleznete v následujících zdrojích:

Doporučujeme použít nové okno prohlížeče v privátním režimu (například režim InPrivate microsoft Edge nebo anonymní režim Google Chrome) pro každý testovací běh aplikace po změně aplikace, konfigurace aplikace nebo služeb Azure na webu Azure Portal. Při cookietestování lokality může docházet k selhání ověřování nebo autorizaci při testování lokality i v případě, že je konfigurace lokality správná. Další informace o tom, jak nakonfigurovat Sadu Visual Studio tak, aby otevřela nové okno privátního prohlížeče pro každé testovací spuštění, najdete v Cookiečásti s a data webu.

Když se konfigurace služby App Service změní na webu Azure Portal, aktualizace se obecně projeví rychle, ale nejsou okamžité. Někdy musíte chvíli počkat, než se služba App Service restartuje, aby se změna konfigurace projevila.

Pokud řešíte potíže s načítáním Identity certifikátu pro podepisování klíčů serveru, spusťte v příkazovém prostředí PowerShellu Kudu na webu Azure Portal následující příkaz. Příkaz poskytuje seznam certifikátů, ke kterým má aplikace přístup z CurrentUser>My úložiště certifikátů. Výstup zahrnuje předměty certifikátů a kryptografické otisky užitečné při ladění aplikace:

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

Odstraňování potíží

Protokolování

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

Běžné chyby

  • Chybná konfigurace aplikace nebo Identity poskytovatele (IP)

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

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

    V oddílech konfigurace pokynů v tomto článku najdete příklady správné konfigurace. Pečlivě zkontrolujte každou část článku, ve které hledáte chybnou konfiguraci aplikace a IP adresy.

    Pokud se konfigurace zobrazí správně:

    • Analyzujte protokoly aplikace.

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

    • U verzí Blazor , ve JSkterých se používá on Web Token (JWT), dekódujte obsah tokenu, který se používá k ověřování klienta nebo přístupu k webovému rozhraní API serveru, v závislosti na tom, kde k problému dochází. Další informace naleznete v tématu Kontrola obsahu JSON Web Token (JWT).

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

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

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

  • Neautorizovaný klient pro ME-ID

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

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

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

    Řešení chyby:

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

Cookies a data lokality

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

  • Přihlášení cookieuživatele
  • Aplikace cookie
  • Uložená a uložená data lokality v mezipaměti

Jedním z přístupů, jak zabránit tomu, aby se při testování a řešení potíží zabránilo přetrvávání cookiedat lokality, je:

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

Upgrady aplikací

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

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

Poznámka:

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

Server Spuštění aplikace

Při testování a řešení potíží s hostovaným Blazor WebAssemblyřešením se ujistěte, že aplikaci spouštíte z Server projektu.

Kontrola uživatele

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

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

Kontrola obsahu webového tokenu JSON (JWT)

K dekódování webového tokenu JS(JWT) použijte nástroj microsoftu jwt.ms . Hodnoty v uživatelském rozhraní nikdy neopustí prohlížeč.

Příklad kódovaného JWT (zkrácený pro zobrazení):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Příklad dekódování JWT nástrojem pro aplikaci, která se ověřuje v Azure AAD B2C:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/5cc15ea8-a296-4aa3-97e4-226dcc9ad298/v2.0/",
  "sub": "5ee963fb-24d6-4d72-a1b6-889c6e2c7438",
  "aud": "70bde375-fce3-4b82-984a-b247d823a03f",
  "nonce": "b2641f54-8dc4-42ca-97ea-7f12ff4af871",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

Další materiály