ASP.NET stato di autenticazione core Blazor

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 9 di questo articolo.

Questo articolo illustra come creare un provider di stato di autenticazione personalizzato e ricevere notifiche di modifica dello stato di autenticazione utente nel codice.

Gli approcci generali eseguiti per le app lato server e lato Blazor client sono simili, ma differiscono nelle implementazioni esatte, quindi questo articolo pivot tra app lato server e app lato Blazor Blazor client. Usare il selettore pivot nella parte superiore dell'articolo per modificare il pivot dell'articolo in modo che corrisponda al tipo di Blazor progetto usato:

  • App lato Blazor server (Server pivot): Blazor Server per .NET 7 o versioni precedenti e il progetto server di un Blazor Web App per .NET 8 o versione successiva.
  • App lato Blazor client (Blazor WebAssembly pivot): Blazor WebAssembly per tutte le versioni di .NET o il .Client progetto di un Blazor Web App per .NET 8 o versioni successive.

Classe astratta AuthenticationStateProvider

Il Blazor framework include una classe astratta AuthenticationStateProvider per fornire informazioni sullo stato di autenticazione dell'utente corrente con i membri seguenti:

Implementare un AuthenticationStateProvider personalizzato

L'app deve fare riferimento al Microsoft.AspNetCore.Components.Authorization pacchetto NuGet, che fornisce supporto per l'autenticazione e l'autorizzazione per Blazor le app.

Nota

Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli sotto Installare e gestire pacchetti in Flusso di lavoro dell'utilizzo di pacchetti (documentazione di NuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.

Configurare i servizi di stato di autenticazione, autorizzazione e propagazione seguenti nel Program file.

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app è preconfigurata con le registrazioni del servizio seguenti, che include l'esposizione dello stato di autenticazione come parametro a catena. Per altre informazioni, vedere ASP.NET'autenticazione e autorizzazione di base Blazor con informazioni aggiuntive presentate nella sezione Personalizzare il contenuto non autorizzato con il Router componente.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();
builder.Services.AddCascadingAuthenticationState();

Configurare i servizi di autenticazione e autorizzazione nel Program file.

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app include la registrazione del servizio seguente.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorization();

Configurare i servizi di autenticazione e autorizzazione in Startup.ConfigureServices .Startup.cs

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app include la registrazione del servizio seguente.

using Microsoft.AspNetCore.Components.Authorization;

...

services.AddAuthorization();

Nelle Blazor WebAssembly app (tutte le versioni di .NET) o nel .Client progetto di un Blazor Web App oggetto (.NET 8 o versione successiva), configurare i servizi di autenticazione, autorizzazione e stato di autenticazione a catena nel Program file.

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app è preconfigurata con le registrazioni del servizio seguenti, che include l'esposizione dello stato di autenticazione come parametro a catena. Per altre informazioni, vedere ASP.NET'autenticazione e autorizzazione di base Blazor con informazioni aggiuntive presentate nella sezione Personalizzare il contenuto non autorizzato con il Router componente.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();

Configurare i servizi di autenticazione e autorizzazione nel Program file.

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app include la registrazione del servizio seguente.

using Microsoft.AspNetCore.Components.Authorization;

...

builder.Services.AddAuthorizationCore();

Sottoclasse AuthenticationStateProvider e override GetAuthenticationStateAsync per creare lo stato di autenticazione dell'utente. Nell'esempio seguente tutti gli utenti vengono autenticati con il nome utente mrfibuli.

CustomAuthStateProvider.cs:

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

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, "mrfibuli"),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }
}

Nota

Il codice precedente che crea un nuovo ClaimsIdentity usa l'inizializzazione semplificata della raccolta introdotta con C# 12 (.NET 8). Per altre informazioni, vedere Espressioni di raccolta - Riferimenti al linguaggio C#.

Il CustomAuthStateProvider servizio viene registrato nel Program file. Registrare l'ambito del servizio con AddScoped:

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

In un'app Blazor Server registrare l'ambito del servizio dopoAddScoped la chiamata a :AddServerSideBlazor

builder.Services.AddServerSideBlazor();

builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

In un'app Blazor Server registrare l'ambito del servizio dopoAddScoped la chiamata a :AddServerSideBlazor

services.AddServerSideBlazor();

services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

Il CustomAuthStateProvider servizio viene registrato nel Program file. Registrare il singleton del servizio con AddSingleton:

builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>();

Se non è presente, aggiungere un'istruzione @using al _Imports.razor file per rendere disponibile lo Microsoft.AspNetCore.Components.Authorization spazio dei nomi tra i componenti:

@using Microsoft.AspNetCore.Components.Authorization;

Confermare o modificare il componente di visualizzazione route in un AuthorizeRouteView oggetto nella definizione del Router componente. La posizione del Router componente varia a seconda del tipo di app. Usare la ricerca per individuare il componente se non si è a conoscenza del relativo percorso nel progetto.

<Router ...>
    <Found ...>
        <AuthorizeRouteView RouteData="routeData" 
            DefaultLayout="typeof(Layout.MainLayout)" />
        ...
    </Found>
</Router>

Nota

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con l'autenticazione abilitata, l'app include il AuthorizeRouteView componente . Per altre informazioni, vedere ASP.NET'autenticazione e autorizzazione di base Blazor con informazioni aggiuntive presentate nella sezione Personalizzare il contenuto non autorizzato con il Router componente.

Dove si trova il Router componente:

La posizione del Router componente varia a seconda del tipo di app. Usare la ricerca per individuare il componente se non si è a conoscenza del relativo percorso nel progetto.

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="routeData" 
                DefaultLayout="typeof(MainLayout)" />
            ...
        </Found>
    </Router>
</CascadingAuthenticationState>

Nota

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con l'autenticazione abilitata, l'app include i AuthorizeRouteView componenti e CascadingAuthenticationState . Per altre informazioni, vedere ASP.NET'autenticazione e autorizzazione di base Blazor con informazioni aggiuntive presentate nella sezione Personalizzare il contenuto non autorizzato con il Router componente.

Il componente di esempio AuthorizeView seguente illustra il nome dell'utente autenticato:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

Per indicazioni sull'uso di AuthorizeView, vedere ASP.NET Autenticazione e autorizzazione di baseBlazor.

Notifiche di modifica dello stato di autenticazione

Un oggetto personalizzato AuthenticationStateProvider può richiamare NotifyAuthenticationStateChanged sulla AuthenticationStateProvider classe di base per notificare ai consumer la modifica dello stato di autenticazione per il rerender.

L'esempio seguente si basa sull'implementazione di un oggetto personalizzato AuthenticationStateProvider seguendo le indicazioni riportate nella sezione Implementare una personalizzata AuthenticationStateProvider in precedenza in questo articolo. Se sono già state seguite le indicazioni riportate in questa sezione, la seguente CustomAuthStateProvider sostituisce quella illustrata nella sezione .

L'implementazione seguente CustomAuthStateProvider espone un metodo personalizzato, AuthenticateUser, per accedere a un utente e notificare ai consumer la modifica dello stato di autenticazione.

CustomAuthStateProvider.cs:

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

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        var identity = new ClaimsIdentity();
        var user = new ClaimsPrincipal(identity);

        return Task.FromResult(new AuthenticationState(user));
    }

    public void AuthenticateUser(string userIdentifier)
    {
        var identity = new ClaimsIdentity(
        [
            new Claim(ClaimTypes.Name, userIdentifier),
        ], "Custom Authentication");

        var user = new ClaimsPrincipal(identity);

        NotifyAuthenticationStateChanged(
            Task.FromResult(new AuthenticationState(user)));
    }
}

Nota

Il codice precedente che crea un nuovo ClaimsIdentity usa l'inizializzazione semplificata della raccolta introdotta con C# 12 (.NET 8). Per altre informazioni, vedere Espressioni di raccolta - Riferimenti al linguaggio C#.

In un componente:

  • Inserimento di AuthenticationStateProvider.
  • Aggiungere un campo per contenere l'identificatore dell'utente.
  • Aggiungere un pulsante e un metodo a cui eseguire il AuthenticationStateProvider CustomAuthStateProvider cast e chiamare AuthenticateUser con l'identificatore dell'utente.
@inject AuthenticationStateProvider AuthenticationStateProvider

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        ((CustomAuthStateProvider)AuthenticationStateProvider)
            .AuthenticateUser(userIdentifier);
    }
}

L'approccio precedente può essere migliorato per attivare le notifiche delle modifiche dello stato di autenticazione tramite un servizio personalizzato. La classe seguente CustomAuthenticationService gestisce l'entità attestazioni dell'utente corrente in un campo sottostante () con un evento (currentUserUserChanged) che il provider di stato di autenticazione può sottoscrivere, in cui l'evento richiama NotifyAuthenticationStateChanged. Con la configurazione aggiuntiva più avanti in questa sezione, CustomAuthenticationService è possibile inserire in un componente con logica che imposta l'oggetto CurrentUser per attivare l'evento UserChanged .

CustomAuthenticationService.cs:

using System.Security.Claims;

public class CustomAuthenticationService
{
    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);
            }
        }
    }
}

Program Nel file registrare CustomAuthenticationService nel contenitore di inserimento delle dipendenze:

builder.Services.AddScoped<CustomAuthenticationService>();

In Startup.ConfigureServices , Startup.csregistrare nel CustomAuthenticationService contenitore di inserimento delle dipendenze:

services.AddScoped<CustomAuthenticationService>();

Program Nel file registrare CustomAuthenticationService nel contenitore di inserimento delle dipendenze:

builder.Services.AddSingleton<CustomAuthenticationService>();

Il codice seguente CustomAuthStateProvider sottoscrive l'evento CustomAuthenticationService.UserChanged . Il GetAuthenticationStateAsync metodo restituisce lo stato di autenticazione dell'utente. Inizialmente, lo stato di autenticazione è basato sul valore di CustomAuthenticationService.CurrentUser. Quando l'utente cambia, viene creato un nuovo stato di autenticazione per il nuovo utente (new AuthenticationState(newUser)) per le chiamate a GetAuthenticationStateAsync:

using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    private AuthenticationState authenticationState;

    public CustomAuthStateProvider(CustomAuthenticationService service)
    {
        authenticationState = new AuthenticationState(service.CurrentUser);

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

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

Il metodo del SignIn componente seguente crea un'entità attestazioni per l'identificatore dell'utente da impostare su CustomAuthenticationService.CurrentUser:

@using System.Security.Claims
@inject CustomAuthenticationService AuthService

<input @bind="userIdentifier" />
<button @onclick="SignIn">Sign in</button>

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    public string userIdentifier = string.Empty;

    private void SignIn()
    {
        var currentUser = AuthService.CurrentUser;

        var identity = new ClaimsIdentity(
            [
                new Claim(ClaimTypes.Name, userIdentifier),
            ],
            "Custom Authentication");

        var newUser = new ClaimsPrincipal(identity);

        AuthService.CurrentUser = newUser;
    }
}

Nota

Il codice precedente che crea un nuovo ClaimsIdentity usa l'inizializzazione semplificata della raccolta introdotta con C# 12 (.NET 8). Per altre informazioni, vedere Espressioni di raccolta - Riferimenti al linguaggio C#.

Risorse aggiuntive