Ověřování a autorizace ASP.NET Core Blazor Hybrid

Poznámka:

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

Důležité

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

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Tento článek popisuje podporu konfigurace a správy zabezpečení ASP.NET Core a ASP.NET Core Identity v aplikacích Blazor Hybrid.

Ověřování v aplikacích Blazor Hybrid se zpracovává nativními knihovnami platformy, protože nabízejí vylepšené záruky zabezpečení, které sandbox prohlížeče nemůže poskytnout. Ověřování nativních aplikací používá mechanismus specifický pro operační systém nebo federovaný protokol, jako je OpenID Connect (OIDC). Postupujte podle pokynů pro zprostředkovatele identity, kterého jste vybrali pro aplikaci, a pak pomocí pokynů v tomto článku dále integrujte identitu s Blazor.

Integrace ověřování musí pro komponenty Razor a služby dosáhnout následujících cílů:

  • Použití abstrakce v balíčku Microsoft.AspNetCore.Components.Authorization, například AuthorizeView
  • Reakce na změny v kontextu ověřování
  • Přístup k přihlašovacím údajům zřízeným aplikací od zprostředkovatele identity, jako jsou přístupové tokeny, k provádění autorizovaných volání rozhraní API

Po přidání ověřování do aplikace .NET MAUI, WPF nebo Windows Forms a poté, co se uživatelé můžou úspěšně přihlásit a odhlásit, integrujte ověřování s Blazor, aby byl ověřený uživatel přístupný komponentám Razor a službám. Proveďte následující kroky:

Aplikace .NET MAUI používají Xamarin.Essentials: Web Authenticator: Třída WebAuthenticator umožňuje aplikaci inicializovat toky ověřování založené na prohlížeči, které naslouchají zpětnému volání na konkrétní adrese URL registrované v aplikaci.

Další doprovodné materiály najdete v následujících zdrojích informací:

model Windows Forms aplikace používají Microsoft Identity Platform pro integraci s Microsoft Entra (ME-ID) a AAD B2C Další informace najdete v tématu Přehled knihovny MSAL (Microsoft Authentication Library).

Vytvoření vlastního AuthenticationStateProvider bez aktualizací změn uživatelů

Pokud aplikace ověří uživatele hned po spuštění aplikace a ověřený uživatel zůstane stejný pro celou dobu života aplikace, oznámení o změnách uživatelů se nevyžadují a aplikace poskytuje pouze informace o ověřeném uživateli. V tomto scénáři se uživatel přihlásí k aplikaci při otevření aplikace a aplikace znovu zobrazí přihlašovací obrazovku po odhlášení uživatele. Následující ExternalAuthStateProvider je příkladem implementace vlastního AuthenticationStateProvider pro tento scénář ověřování.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private readonly Task<AuthenticationState> authenticationState;

    public ExternalAuthStateProvider(AuthenticatedUser user) => 
        authenticationState = Task.FromResult(new AuthenticationState(user.Principal));

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        authenticationState;
}

public class AuthenticatedUser
{
    public ClaimsPrincipal Principal { get; set; } = new();
}

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.
  • Vrácení sestaveného hostitele.

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který vrací sestavení Microsoft.Maui.Hosting.MauiApp:

- return builder.Build();

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

builder.Services.AddAuthorizationCore();
builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
builder.Services.AddSingleton<AuthenticatedUser>();
var host = builder.Build();

var authenticatedUser = host.Services.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

return host;

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb a přidání sestavené kolekce služeb jako prostředek do ResourceDictionary aplikace.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.
  • Vrácení sestaveného hostitele.

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který přidá sestavenou kolekci služeb jako prostředek do ResourceDictionary aplikace:

- Resources.Add("services", serviceCollection.BuildServiceProvider());

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

serviceCollection.AddAuthorizationCore();
serviceCollection.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
serviceCollection.AddSingleton<AuthenticatedUser>();
var services = serviceCollection.BuildServiceProvider();
Resources.Add("services", services);

var authenticatedUser = services.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb a přidání sestavené kolekce služeb do poskytovatele služeb aplikace.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

V konstruktoru třídy Form1 (Form1.cs) přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který nastavuje sestavenou kolekci služeb na poskytovatele služeb aplikace:

- blazorWebView1.Services = services.BuildServiceProvider();

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

services.AddAuthorizationCore();
services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
services.AddSingleton<AuthenticatedUser>();
var serviceCollection = services.BuildServiceProvider();
blazorWebView1.Services = serviceCollection;

var authenticatedUser = serviceCollection.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

Vytvoření vlastního AuthenticationStateProvider s aktualizacemi změn uživatelů

Pokud chcete aktualizovat uživatele během spuštění aplikace Blazor, zavolejte NotifyAuthenticationStateChanged v rámci implementace AuthenticationStateProvider pomocí jednoho z následujících přístupů:

Signalizace aktualizace ověřování mimo BlazorWebView (možnost 1)

Vlastní AuthenticationStateProvider může pomocí globální služby signalizovat aktualizaci ověřování. Doporučujeme, aby služba nabízela událost, k odběru které se může AuthenticationStateProvider přihlásit, kdy událost vyvolá NotifyAuthenticationStateChanged.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private AuthenticationState currentUser;

    public ExternalAuthStateProvider(ExternalAuthService service)
    {
        currentUser = new AuthenticationState(service.CurrentUser);

        service.UserChanged += (newUser) =>
        {
            currentUser = new AuthenticationState(newUser);
            NotifyAuthenticationStateChanged(Task.FromResult(currentUser));
        };
    }

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(currentUser);
}

public class ExternalAuthService
{
    public event Action<ClaimsPrincipal>? UserChanged;
    private ClaimsPrincipal? currentUser;

    public ClaimsPrincipal CurrentUser
    {
        get { return currentUser ?? new(); }
        set
        {
            currentUser = value;

            if (UserChanged is not null)
            {
                UserChanged(currentUser);
            }
        }
    }
}

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

builder.Services.AddAuthorizationCore();
builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
builder.Services.AddSingleton<ExternalAuthService>();

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

serviceCollection.AddAuthorizationCore();
serviceCollection.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
serviceCollection.AddSingleton<ExternalAuthService>();

V konstruktoru třídy Form1 (Form1.cs) přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

services.AddAuthorizationCore();
services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
services.AddSingleton<ExternalAuthService>();

Kdykoli aplikace ověří uživatele, vyřešte službu ExternalAuthService:

var authService = host.Services.GetRequiredService<ExternalAuthService>();

Spusťte vlastní kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity. Ověřený uživatel (authenticatedUser v následujícím příkladu) je nový ClaimsPrincipal na základě nového ClaimsIdentity.

Nastavte aktuálního uživatele na ověřeného uživatele:

authService.CurrentUser = authenticatedUser;

Alternativou k předchozímu přístupu je nastavení instančního objektu uživatele pro System.Threading.Thread.CurrentPrincipal, místo nastavení prostřednictvím služby, což zabraňuje použití kontejneru injektáže závislostí:

public class CurrentThreadUserAuthenticationStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(
            new AuthenticationState(Thread.CurrentPrincipal as ClaimsPrincipal ?? 
                new ClaimsPrincipal(new ClaimsIdentity())));
}

Při použití alternativního přístupu se do kolekce služeb přidají pouze autorizační služby (AddAuthorizationCore) a CurrentThreadUserAuthenticationStateProvider (.TryAddScoped<AuthenticationStateProvider, CurrentThreadUserAuthenticationStateProvider>()).

Zpracování ověřování v rámci BlazorWebView (možnost 2)

Vlastní AuthenticationStateProvider může zahrnovat další metody pro aktivaci přihlášení a odhlášení a aktualizaci uživatele.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private ClaimsPrincipal currentUser = new ClaimsPrincipal(new ClaimsIdentity());

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(new AuthenticationState(currentUser));

    public Task LogInAsync()
    {
        var loginTask = LogInAsyncCore();
        NotifyAuthenticationStateChanged(loginTask);

        return loginTask;

        async Task<AuthenticationState> LogInAsyncCore()
        {
            var user = await LoginWithExternalProviderAsync();
            currentUser = user;

            return new AuthenticationState(currentUser);
        }
    }

    private Task<ClaimsPrincipal> LoginWithExternalProviderAsync()
    {
        /*
            Provide OpenID/MSAL code to authenticate the user. See your identity 
            provider's documentation for details.

            Return a new ClaimsPrincipal based on a new ClaimsIdentity.
        */
        var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity());

        return Task.FromResult(authenticatedUser);
    }

    public void Logout()
    {
        currentUser = new ClaimsPrincipal(new ClaimsIdentity());
        NotifyAuthenticationStateChanged(
            Task.FromResult(new AuthenticationState(currentUser)));
    }
}

V předchozím příkladu:

  • Volání LogInAsyncCore aktivuje proces přihlášení.
  • Volání NotifyAuthenticationStateChanged upozorní, že probíhá aktualizace, což aplikaci umožňuje poskytnout dočasné uživatelské rozhraní během procesu přihlášení nebo odhlášení.
  • Vrácení loginTask vrátí úlohu, aby komponenta, která aktivovala přihlášení, mohla čekat a reagovat po dokončení úlohy.
  • Metoda LoginWithExternalProviderAsync je implementována vývojářem pro přihlášení uživatele pomocí sady SDK zprostředkovatele identity. Další informace najdete v dokumentaci zprostředkovatele identity. Ověřený uživatel (authenticatedUser) je nový ClaimsPrincipal na základě nového ClaimsIdentity.

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

builder.Services.AddAuthorizationCore();
builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

serviceCollection.AddAuthorizationCore();
serviceCollection.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

V konstruktoru třídy Form1 (Form1.cs) přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

services.AddAuthorizationCore();
services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

Následující komponenta LoginComponent ukazuje, jak přihlásit uživatele. V typické aplikaci se komponenta LoginComponent zobrazuje jenom v nadřazené komponentě, pokud uživatel není přihlášený k aplikaci.

Shared/LoginComponent.razor:

@inject AuthenticationStateProvider AuthenticationStateProvider

<button @onclick="Login">Log in</button>

@code
{
    public async Task Login()
    {
        await ((ExternalAuthStateProvider)AuthenticationStateProvider)
            .LogInAsync();
    }
}

Následující komponenta LogoutComponent ukazuje, jak odhlásit uživatele. V typické aplikaci se komponenta LogoutComponent zobrazuje jenom v nadřazené komponentě, pokud uživatel je přihlášený k aplikaci.

Shared/LogoutComponent.razor:

@inject AuthenticationStateProvider AuthenticationStateProvider

<button @onclick="Logout">Log out</button>

@code
{
    public async Task Logout()
    {
        await ((ExternalAuthStateProvider)AuthenticationStateProvider)
            .Logout();
    }
}

Přístup k jiným ověřovacím informacím

Blazor nedefinuje abstrakci pro zpracování jiných přihlašovacích údajů, jako jsou přístupové tokeny, které se mají použít pro požadavky HTTP na webová rozhraní API. Doporučujeme postupovat podle pokynů zprostředkovatele identity ke správě přihlašovacích údajů uživatele pomocí primitiv, která poskytuje sada SDK zprostředkovatele identity.

Pro sady SDK zprostředkovatele identit je běžné používat úložiště tokenů pro přihlašovací údaje uživatele uložené v zařízení. Pokud se do kontejneru služby přidá primitivum úložiště tokenů sady SDK, spotřebujte primitivum sady SDK v rámci aplikace.

Architektura Blazor neví o přihlašovacích údajích uživatele a nijak nepracuje s přihlašovacími údaji, takže kód aplikace může volně používat jakýkoli přístup, který považujete za nejvhodnější. Při implementaci ověřovacího kódu v aplikaci ale postupujte podle obecných pokynů k zabezpečení v další části, Další aspekty zabezpečení ověřování.

Další aspekty zabezpečení ověřování

Proces ověřování je externí vzhledem k Blazor a doporučujeme, aby vývojáři využívali doprovodné materiály zprostředkovatele identit k získání dalších pokynů k zabezpečení.

Při implementaci ověřování:

  • Vyhněte se ověřování v kontextu Web View. Nepoužívejte například knihovnu JavaScript OAuth k provádění toku ověřování. V jednostránkové aplikaci nejsou ověřovací tokeny skryté v JavaScriptu a můžou je snadno zjistit uživatelé se zlými úmysly a zneužít je. Nativní aplikace tímto rizikem netrpí, protože nativní aplikace můžou získat tokeny pouze mimo kontext prohlížeče, což znamená, že skripty třetích stran se zlými úmysly nemůžou tokeny ukrást a ohrozit aplikaci.
  • Vyhněte se vlastní implementaci pracovního postupu ověřování. Ve většině případů knihovny platforem bezpečně zpracovávají pracovní postup ověřování pomocí prohlížeče systému místo vlastního Web View, který je možné zneužít.
  • Vyhněte se použití ovládacího prvku Web View platformy k provedení ověřování. Místo toho v případech, kdy je to možné, spoléhejte na prohlížeč systému.
  • Vyhněte se předávání tokenů do kontextu dokumentu (JavaScript). V některých situacích je k provedení autorizovaného volání externí služby vyžadována javascriptová knihovna v dokumentu. Místo zpřístupnění tokenu pro JavaScript prostřednictvím JS zprostředkovatele komunikace:
    • Poskytněte knihovně a v rámci Web View vygenerovaný dočasný token.
    • Zachyťte odchozí síťový požadavek v kódu.
    • Nahraďte dočasný token skutečným tokenem a ověřte, že cíl požadavku je platný.

Další materiály

Ověřování v aplikacích Blazor Hybrid se zpracovává nativními knihovnami platformy, protože nabízejí vylepšené záruky zabezpečení, které sandbox prohlížeče nemůže poskytnout. Ověřování nativních aplikací používá mechanismus specifický pro operační systém nebo federovaný protokol, jako je OpenID Connect (OIDC). Postupujte podle pokynů pro zprostředkovatele identity, kterého jste vybrali pro aplikaci, a pak pomocí pokynů v tomto článku dále integrujte identitu s Blazor.

Integrace ověřování musí pro komponenty Razor a služby dosáhnout následujících cílů:

  • Použití abstrakce v balíčku Microsoft.AspNetCore.Components.Authorization, například AuthorizeView
  • Reakce na změny v kontextu ověřování
  • Přístup k přihlašovacím údajům zřízeným aplikací od zprostředkovatele identity, jako jsou přístupové tokeny, k provádění autorizovaných volání rozhraní API

Po přidání ověřování do aplikace .NET MAUI, WPF nebo Windows Forms a poté, co se uživatelé můžou úspěšně přihlásit a odhlásit, integrujte ověřování s Blazor, aby byl ověřený uživatel přístupný komponentám Razor a službám. Proveďte následující kroky:

Aplikace .NET MAUI používají Xamarin.Essentials: Web Authenticator: Třída WebAuthenticator umožňuje aplikaci inicializovat toky ověřování založené na prohlížeči, které naslouchají zpětnému volání na konkrétní adrese URL registrované v aplikaci.

Další doprovodné materiály najdete v následujících zdrojích informací:

model Windows Forms aplikace používají Microsoft Identity Platform pro integraci s Microsoft Entra (ME-ID) a AAD B2C Další informace najdete v tématu Přehled knihovny MSAL (Microsoft Authentication Library).

Vytvoření vlastního AuthenticationStateProvider bez aktualizací změn uživatelů

Pokud aplikace ověří uživatele hned po spuštění aplikace a ověřený uživatel zůstane stejný pro celou dobu života aplikace, oznámení o změnách uživatelů se nevyžadují a aplikace poskytuje pouze informace o ověřeném uživateli. V tomto scénáři se uživatel přihlásí k aplikaci při otevření aplikace a aplikace znovu zobrazí přihlašovací obrazovku po odhlášení uživatele. Následující ExternalAuthStateProvider je příkladem implementace vlastního AuthenticationStateProvider pro tento scénář ověřování.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private readonly Task<AuthenticationState> authenticationState;

    public ExternalAuthStateProvider(AuthenticatedUser user) => 
        authenticationState = Task.FromResult(new AuthenticationState(user.Principal));

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        authenticationState;
}

public class AuthenticatedUser
{
    public ClaimsPrincipal Principal { get; set; } = new();
}

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.
  • Vrácení sestaveného hostitele.

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který vrací sestavení Microsoft.Maui.Hosting.MauiApp:

- return builder.Build();

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
builder.Services.AddSingleton<AuthenticatedUser>();
var host = builder.Build();

var authenticatedUser = host.Services.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

return host;

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb a přidání sestavené kolekce služeb jako prostředek do ResourceDictionary aplikace.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.
  • Vrácení sestaveného hostitele.

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který přidá sestavenou kolekci služeb jako prostředek do ResourceDictionary aplikace:

- Resources.Add("services", serviceCollection.BuildServiceProvider());

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

serviceCollection.AddAuthorizationCore();
serviceCollection.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
serviceCollection.AddSingleton<AuthenticatedUser>();
var services = serviceCollection.BuildServiceProvider();
Resources.Add("services", services);

var authenticatedUser = services.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

Následující kroky popisují:

  • Přidání požadovaných oborů názvů.
  • Přidání autorizačních služeb a abstrakcí Blazor do kolekce služeb.
  • Sestavení kolekce služeb a přidání sestavené kolekce služeb do poskytovatele služeb aplikace.
  • Vyřešení služby AuthenticatedUser pro nastavení instančního objektu deklarací identity ověřeného uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

V konstruktoru třídy Form1 (Form1.cs) přidejte obory názvů pro Microsoft.AspNetCore.Components.Authorization a System.Security.Claims:

using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;

Odeberte následující řádek kódu, který nastavuje sestavenou kolekci služeb na poskytovatele služeb aplikace:

- blazorWebView1.Services = services.BuildServiceProvider();

Nahraďte předchozí řádek kódu následujícím kódem. Přidejte kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity.

services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
services.AddSingleton<AuthenticatedUser>();
var serviceCollection = services.BuildServiceProvider();
blazorWebView1.Services = serviceCollection;

var authenticatedUser = serviceCollection.GetRequiredService<AuthenticatedUser>();

/*
Provide OpenID/MSAL code to authenticate the user. See your identity provider's 
documentation for details.

The user is represented by a new ClaimsPrincipal based on a new ClaimsIdentity.
*/
var user = new ClaimsPrincipal(new ClaimsIdentity());

authenticatedUser.Principal = user;

Vytvoření vlastního AuthenticationStateProvider s aktualizacemi změn uživatelů

Pokud chcete aktualizovat uživatele během spuštění aplikace Blazor, zavolejte NotifyAuthenticationStateChanged v rámci implementace AuthenticationStateProvider pomocí jednoho z následujících přístupů:

Signalizace aktualizace ověřování mimo BlazorWebView (možnost 1)

Vlastní AuthenticationStateProvider může pomocí globální služby signalizovat aktualizaci ověřování. Doporučujeme, aby služba nabízela událost, k odběru které se může AuthenticationStateProvider přihlásit, kdy událost vyvolá NotifyAuthenticationStateChanged.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private AuthenticationState currentUser;

    public ExternalAuthStateProvider(ExternalAuthService service)
    {
        currentUser = new AuthenticationState(service.CurrentUser);

        service.UserChanged += (newUser) =>
        {
            currentUser = new AuthenticationState(newUser);
            NotifyAuthenticationStateChanged(Task.FromResult(currentUser));
        };
    }

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(currentUser);
}

public class ExternalAuthService
{
    public event Action<ClaimsPrincipal>? UserChanged;
    private ClaimsPrincipal? currentUser;

    public ClaimsPrincipal CurrentUser
    {
        get { return currentUser ?? new(); }
        set
        {
            currentUser = value;

            if (UserChanged is not null)
            {
                UserChanged(currentUser);
            }
        }
    }
}

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
builder.Services.AddSingleton<ExternalAuthService>();

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

serviceCollection.AddAuthorizationCore();
serviceCollection.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
serviceCollection.AddSingleton<ExternalAuthService>();

V konstruktoru třídy Form1 (Form1.cs) přidejte obor názvů pro Microsoft.AspNetCore.Components.Authorization:

using Microsoft.AspNetCore.Components.Authorization;

Přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
services.AddSingleton<ExternalAuthService>();

Kdykoli aplikace ověří uživatele, vyřešte službu ExternalAuthService:

var authService = host.Services.GetRequiredService<ExternalAuthService>();

Spusťte vlastní kód OpenID/MSAL pro ověření uživatele. Podrobnosti najdete v dokumentaci zprostředkovatele identity. Ověřený uživatel (authenticatedUser v následujícím příkladu) je nový ClaimsPrincipal na základě nového ClaimsIdentity.

Nastavte aktuálního uživatele na ověřeného uživatele:

authService.CurrentUser = authenticatedUser;

Alternativou k předchozímu přístupu je nastavení instančního objektu uživatele pro System.Threading.Thread.CurrentPrincipal, místo nastavení prostřednictvím služby, což zabraňuje použití kontejneru injektáže závislostí:

public class CurrentThreadUserAuthenticationStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(
            new AuthenticationState(Thread.CurrentPrincipal as ClaimsPrincipal ?? 
                new ClaimsPrincipal(new ClaimsIdentity())));
}

Při použití alternativního přístupu se do kolekce služeb přidají pouze autorizační služby (AddAuthorizationCore) a CurrentThreadUserAuthenticationStateProvider (.AddScoped<AuthenticationStateProvider, CurrentThreadUserAuthenticationStateProvider>()).

Zpracování ověřování v rámci BlazorWebView (možnost 2)

Vlastní AuthenticationStateProvider může zahrnovat další metody pro aktivaci přihlášení a odhlášení a aktualizaci uživatele.

Poznámka:

Následující vlastní AuthenticationStateProvider nedeklaruje obor názvů, aby byl příklad kódu použitelný pro jakoukoli aplikaci Blazor Hybrid. Osvědčeným postupem při implementaci příkladu v produkční aplikaci je ale poskytnout obor názvů vaší aplikace.

ExternalAuthStateProvider.cs:

using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;

public class ExternalAuthStateProvider : AuthenticationStateProvider
{
    private ClaimsPrincipal currentUser = new ClaimsPrincipal(new ClaimsIdentity());

    public override Task<AuthenticationState> GetAuthenticationStateAsync() =>
        Task.FromResult(new AuthenticationState(currentUser));

    public Task LogInAsync()
    {
        var loginTask = LogInAsyncCore();
        NotifyAuthenticationStateChanged(loginTask);

        return loginTask;

        async Task<AuthenticationState> LogInAsyncCore()
        {
            var user = await LoginWithExternalProviderAsync();
            currentUser = user;

            return new AuthenticationState(currentUser);
        }
    }

    private Task<ClaimsPrincipal> LoginWithExternalProviderAsync()
    {
        /*
            Provide OpenID/MSAL code to authenticate the user. See your identity 
            provider's documentation for details.

            Return a new ClaimsPrincipal based on a new ClaimsIdentity.
        */
        var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity());

        return Task.FromResult(authenticatedUser);
    }

    public void Logout()
    {
        currentUser = new ClaimsPrincipal(new ClaimsIdentity());
        NotifyAuthenticationStateChanged(
            Task.FromResult(new AuthenticationState(currentUser)));
    }
}

V předchozím příkladu:

  • Volání LogInAsyncCore aktivuje proces přihlášení.
  • Volání NotifyAuthenticationStateChanged upozorní, že probíhá aktualizace, což aplikaci umožňuje poskytnout dočasné uživatelské rozhraní během procesu přihlášení nebo odhlášení.
  • Vrácení loginTask vrátí úlohu, aby komponenta, která aktivovala přihlášení, mohla čekat a reagovat po dokončení úlohy.
  • Metoda LoginWithExternalProviderAsync je implementována vývojářem pro přihlášení uživatele pomocí sady SDK zprostředkovatele identity. Další informace najdete v dokumentaci zprostředkovatele identity. Ověřený uživatel (authenticatedUser) je nový ClaimsPrincipal na základě nového ClaimsIdentity.

V metodě MauiProgram.CreateMauiApp třídy MauiProgram.cs přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

V konstruktoru třídy MainWindow (MainWindow.xaml.cs) přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

serviceCollection.AddAuthorizationCore();
serviceCollection.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

V konstruktoru třídy Form1 (Form1.cs) přidejte autorizační služby a abstrakce Blazor do kolekce služeb:

services.AddAuthorizationCore();
services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

Následující komponenta LoginComponent ukazuje, jak přihlásit uživatele. V typické aplikaci se komponenta LoginComponent zobrazuje jenom v nadřazené komponentě, pokud uživatel není přihlášený k aplikaci.

Shared/LoginComponent.razor:

@inject AuthenticationStateProvider AuthenticationStateProvider

<button @onclick="Login">Log in</button>

@code
{
    public async Task Login()
    {
        await ((ExternalAuthStateProvider)AuthenticationStateProvider)
            .LogInAsync();
    }
}

Následující komponenta LogoutComponent ukazuje, jak odhlásit uživatele. V typické aplikaci se komponenta LogoutComponent zobrazuje jenom v nadřazené komponentě, pokud uživatel je přihlášený k aplikaci.

Shared/LogoutComponent.razor:

@inject AuthenticationStateProvider AuthenticationStateProvider

<button @onclick="Logout">Log out</button>

@code
{
    public async Task Logout()
    {
        await ((ExternalAuthStateProvider)AuthenticationStateProvider)
            .Logout();
    }
}

Přístup k jiným ověřovacím informacím

Blazor nedefinuje abstrakci pro zpracování jiných přihlašovacích údajů, jako jsou přístupové tokeny, které se mají použít pro požadavky HTTP na webová rozhraní API. Doporučujeme postupovat podle pokynů zprostředkovatele identity ke správě přihlašovacích údajů uživatele pomocí primitiv, která poskytuje sada SDK zprostředkovatele identity.

Pro sady SDK zprostředkovatele identit je běžné používat úložiště tokenů pro přihlašovací údaje uživatele uložené v zařízení. Pokud se do kontejneru služby přidá primitivum úložiště tokenů sady SDK, spotřebujte primitivum sady SDK v rámci aplikace.

Architektura Blazor neví o přihlašovacích údajích uživatele a nijak nepracuje s přihlašovacími údaji, takže kód aplikace může volně používat jakýkoli přístup, který považujete za nejvhodnější. Při implementaci ověřovacího kódu v aplikaci ale postupujte podle obecných pokynů k zabezpečení v další části, Další aspekty zabezpečení ověřování.

Další aspekty zabezpečení ověřování

Proces ověřování je externí vzhledem k Blazor a doporučujeme, aby vývojáři využívali doprovodné materiály zprostředkovatele identit k získání dalších pokynů k zabezpečení.

Při implementaci ověřování:

  • Vyhněte se ověřování v kontextu Web View. Nepoužívejte například knihovnu JavaScript OAuth k provádění toku ověřování. V jednostránkové aplikaci nejsou ověřovací tokeny skryté v JavaScriptu a můžou je snadno zjistit uživatelé se zlými úmysly a zneužít je. Nativní aplikace tímto rizikem netrpí, protože nativní aplikace můžou získat tokeny pouze mimo kontext prohlížeče, což znamená, že skripty třetích stran se zlými úmysly nemůžou tokeny ukrást a ohrozit aplikaci.
  • Vyhněte se vlastní implementaci pracovního postupu ověřování. Ve většině případů knihovny platforem bezpečně zpracovávají pracovní postup ověřování pomocí prohlížeče systému místo vlastního Web View, který je možné zneužít.
  • Vyhněte se použití ovládacího prvku Web View platformy k provedení ověřování. Místo toho v případech, kdy je to možné, spoléhejte na prohlížeč systému.
  • Vyhněte se předávání tokenů do kontextu dokumentu (JavaScript). V některých situacích je k provedení autorizovaného volání externí služby vyžadována javascriptová knihovna v dokumentu. Místo zpřístupnění tokenu pro JavaScript prostřednictvím JS zprostředkovatele komunikace:
    • Poskytněte knihovně a v rámci Web View vygenerovaný dočasný token.
    • Zachyťte odchozí síťový požadavek v kódu.
    • Nahraďte dočasný token skutečným tokenem a ověřte, že cíl požadavku je platný.

Další materiály