Condividi tramite


Autenticazione e autorizzazione per ASP.NET 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 i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 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 descrive il supporto di ASP.NET Core per la configurazione e la gestione della sicurezza nelle app Blazor.

Blazor usa i meccanismi di autenticazione di base di ASP.NET esistenti per stabilire l'oggetto dell'utente identity. Il meccanismo esatto dipende dal modo in cui l'app Blazor è ospitata, lato server o lato client.

Gli scenari di sicurezza variano tra il codice di autorizzazione che esegue il lato server e il lato client nelle Blazor app. Per il codice di autorizzazione eseguito nel server, i controlli di autorizzazione sono in grado di applicare le regole di accesso per le aree dell'app e dei componenti. Poiché l'esecuzione del codice sul lato client può essere manomessa, il codice di autorizzazione in esecuzione nel client non può essere considerato attendibile per applicare assolutamente le regole di accesso o controllare la visualizzazione del contenuto lato client.

Se l'imposizione delle regole di autorizzazione deve essere garantita, non implementare i controlli di autorizzazione nel codice lato client. Compilare un oggetto Blazor Web App che si basa solo sul rendering lato server (SSR) per i controlli di autorizzazione e l'imposizione delle regole.

Se l'imposizione delle regole di autorizzazione e la sicurezza dei dati e del codice devono essere garantiti, non sviluppare un'app sul lato client. Creare un'app Blazor Server .

Le convenzioni di autorizzazione di RazorPages non si applicano ai componenti Razor instradabili. Se un componente non instradabile Razor è incorporato in una pagina di un'app RazorPages, le convenzioni di autorizzazione della pagina influiscono indirettamente sul Razor componente insieme al rest contenuto della pagina.

ASP.NET Core Identity è progettato per funzionare nel contesto della comunicazione di richiesta e risposta HTTP, che in genere non è il modello di comunicazione client-server dell'app Blazor . Le app ASP.NET Core che usano ASP.NET Core Identity per la gestione utenti devono usare Razor Pages anziché componenti Razor per l'interfaccia utente correlata a Identity, ad esempio registrazione utente, accesso, disconnessione e altre attività di gestione utenti. La compilazione di Razor componenti che gestiscono Identity direttamente le attività è possibile per diversi scenari, ma non è consigliata o supportata da Microsoft.

Le astrazioni ASP.NET Core, come SignInManager<TUser> e UserManager<TUser>, non sono supportate nei componenti Razor. Per altre informazioni sull'uso di ASP.NET Core Identity con , vedere Blazor lato Identity server.Blazor

Nota

Gli esempi di codice in questo articolo adottano tipi di riferimento nullable (NRT) e l'analisi statica dello stato null del compilatore .NET, supportati in ASP.NET Core in .NET 6 o versione successiva. Quando la destinazione è ASP.NET Core 5.0 o versioni precedenti, rimuovere la designazione di tipo Null (?) dagli esempi in questo articolo.

Mantenere in modo sicuro dati e credenziali sensibili

Non archiviare segreti dell'app, stringa di connessione, credenziali, password, numeri di identificazione personale (PIN), codice .NET/C# privato o chiavi/token privati nel codice lato client, che è sempre non sicuro. Il codice lato Blazor client deve accedere a servizi e database sicuri tramite un'API Web sicura che si controlla.

Negli ambienti di test/gestione temporanea e produzione, il codice lato Blazor server e le API Web devono usare flussi di autenticazione sicuri che evitano di mantenere le credenziali all'interno del codice del progetto o dei file di configurazione. Al di fuori dei test di sviluppo locali, è consigliabile evitare l'uso di variabili di ambiente per archiviare i dati sensibili, perché le variabili di ambiente non sono l'approccio più sicuro. Per i test di sviluppo locali, lo strumento Secret Manager è consigliato per proteggere i dati sensibili. Per ulteriori informazioni, vedi le seguenti risorse:

Per lo sviluppo e il test locali sul lato client e sul lato server, usare lo strumento Secret Manager per proteggere le credenziali sensibili.

Identità gestite per i servizi di Microsoft Azure

Per i servizi di Microsoft Azure, è consigliabile usare le identità gestite. Le identità gestite eseguono l'autenticazione sicura ai servizi di Azure senza archiviare le credenziali nel codice dell'app. Per ulteriori informazioni, vedi le seguenti risorse:

Supporto antiforgerato

Il Blazor modello:

Il componente esegue il AntiforgeryToken rendering di un token antiforgery come campo nascosto e questo componente viene aggiunto automaticamente alle istanze del modulo (EditForm). Per altre informazioni, vedere Blazor dei moduli principali.

Il AntiforgeryStateProvider servizio fornisce l'accesso a un token antiforgery associato alla sessione corrente. Inserire il servizio e chiamare il GetAntiforgeryToken() relativo metodo per ottenere l'oggetto corrente AntiforgeryRequestToken. Per altre informazioni, vedere Blazor ASP.NET Core.

Blazor archivia i token di richiesta nello stato del componente, che garantisce che i token antiforgery siano disponibili per i componenti interattivi, anche quando non hanno accesso alla richiesta.

Nota

La mitigazione antiforgery è necessaria solo quando si inviano i dati del modulo al server codificati come application/x-www-form-urlencoded, multipart/form-datao text/plain poiché sono gli unici tipi di modulo validi.

Per ulteriori informazioni, vedi le seguenti risorse:

  • Evitare attacchi XSRF/CSRF (Cross-Site Request Forgery) in ASP.NET Core: questo articolo è l'articolo principale ASP.NET Core sull'argomento, che si applica a lato Blazor Serverserver, al progetto server di Blazor Web Apps e Blazor all'integrazione con MVC/Razor Pages.
  • Blazor dei moduli di base: la sezione supporto antiforgery dell'articolo riguarda i Blazor moduli di supporto antiforgery.

Autenticazione lato Blazor server

Le app lato Blazor server vengono configurate per la sicurezza nello stesso modo delle app core ASP.NET. Per altre informazioni, vedere gli articoli negli argomenti dedicati alla sicurezza di ASP.NET Core.

Il contesto di autenticazione viene stabilito solo all'avvio dell'app, ovvero quando l'app si connette per la prima volta al WebSocket tramite una SignalR connessione con il client. L'autenticazione può essere basata su un cookie o su un altro token di connessione, ma l'autenticazione viene gestita tramite l'hub SignalR e interamente all'interno del circuito. Il contesto di autenticazione viene mantenuto per la durata del circuito. Le app riconvalidano periodicamente lo stato di autenticazione dell'utente ogni 30 minuti.

Se l'app deve acquisire gli utenti per i servizi personalizzati o reagire agli aggiornamenti all'utente, vedere Blazor Web App e lato server Core.

Blazor differisce da un'app Web con rendering server tradizionale che effettua nuove richieste HTTP con cookie in ogni spostamento di pagina. L'autenticazione viene verificata durante gli eventi di spostamento. Tuttavia, i cookie non sono coinvolti. I cookie vengono inviati solo quando si effettua una richiesta HTTP a un server, che non avviene quando l'utente si sposta in un'app Blazor . Durante la navigazione, lo stato di autenticazione dell'utente viene controllato all'interno del Blazor circuito, che è possibile aggiornare in qualsiasi momento sul server usando l'astrazioneRevalidatingAuthenticationStateProvider.

Importante

L'implementazione di un personalizzato NavigationManager per ottenere la convalida dell'autenticazione durante la navigazione non è consigliata. Se l'app deve eseguire la logica dello stato di autenticazione personalizzata durante la navigazione, usare un oggetto personalizzato AuthenticationStateProvider.

Nota

Gli esempi di codice in questo articolo adottano tipi di riferimento nullable (NRT) e l'analisi statica dello stato null del compilatore .NET, supportati in ASP.NET Core in .NET 6 o versione successiva. Quando la destinazione è ASP.NET Core 5.0 o versioni precedenti, rimuovere la designazione di tipo Null (?) dagli esempi in questo articolo.

Il servizio predefinito o personalizzato AuthenticationStateProvider ottiene i dati dello stato di autenticazione da ASP.NET Core.HttpContext.User Questo è il modo in cui lo stato di autenticazione si integra con i meccanismi di autenticazione ASP.NET Core esistenti.

Per altre informazioni sull'autenticazione lato server, vedere Blazor di base.

IHttpContextAccessor/HttpContext

In genere, IHttpContextAccessor dovrebbe essere evitato con il rendering interattivo perché un valido HttpContext non è sempre disponibile.

IHttpContextAccessor può essere usato per i componenti di cui viene eseguito il rendering statico nel server. Tuttavia, è consigliabile evitarlo, se possibile.

HttpContext può essere usato come parametro a catena solo nei componenti radice sottoposti a rendering statico per attività generali, ad esempio l'ispezione e la modifica di intestazioni o altre proprietà nel App componente (Components/App.razor). Il valore è sempre null per il rendering interattivo.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Per gli scenari in cui HttpContext è necessario nei componenti interattivi, è consigliabile fluire i dati tramite lo stato del componente persistente dal server. Per altre informazioni, vedere ASP.NET core server-side e Blazor Web App altri scenari di sicurezza.

Non usare IHttpContextAccessor/HttpContext direttamente o indirettamente nei Razor componenti delle app lato Blazor server. Blazor le app vengono eseguite all'esterno del contesto della pipeline core ASP.NET. Non HttpContext è garantito che sia disponibile all'interno di IHttpContextAccessore HttpContext non sia garantito che contenga il contesto che ha avviato l'app Blazor .

L'approccio consigliato per passare lo stato della richiesta all'app consiste nell'usare Blazor i parametri del componente radice durante il rendering iniziale dell'app. In alternativa, l'app può copiare i dati in un servizio con ambito nell'evento del ciclo di vita di inizializzazione del componente radice da usare nell'app. Per altre informazioni, vedere ASP.NET core server-side e Blazor Web App altri scenari di sicurezza.

Un aspetto critico della sicurezza lato Blazor server è che l'utente collegato a un determinato circuito potrebbe essere aggiornato a un certo punto dopo che il Blazor circuito è stato stabilito, ma IHttpContextAccessornon viene aggiornato. Per altre informazioni sulla gestione di questa situazione con i servizi personalizzati, vedere Blazor Web App e lato server core.

Stato condiviso

Le app sul lato Blazor server sono attive in memoria server e più sessioni di app sono ospitate nello stesso processo. Per ogni sessione dell'app, Blazor avvia un circuito con il proprio ambito contenitore di inserimento delle dipendenze, pertanto i servizi con ambito sono univoci per Blazor sessione.

Avviso

Non è consigliabile che le app nello stesso stato di condivisione server usino servizi singleton, a meno che non venga eseguita un'estrema attenzione, in quanto ciò può introdurre vulnerabilità di sicurezza, ad esempio la perdita dello stato utente tra circuiti.

È possibile usare i servizi singleton con stato nelle Blazor app se sono progettati specificamente per esso. Ad esempio, l'uso di una cache di memoria singleton è accettabile perché una cache di memoria richiede una chiave per accedere a una determinata voce. Supponendo che gli utenti non abbiano il controllo sulle chiavi della cache usate con la cache, lo stato archiviato nella cache non perde i circuiti.

Per indicazioni generali sulla gestione dello stato, vedere Blazor dello stato core.

Sicurezza lato server di dati e credenziali sensibili

Negli ambienti di test/gestione temporanea e produzione, il codice lato Blazor server e le API Web devono usare flussi di autenticazione sicuri che evitano di mantenere le credenziali all'interno del codice del progetto o dei file di configurazione. Al di fuori dei test di sviluppo locali, è consigliabile evitare l'uso di variabili di ambiente per archiviare i dati sensibili, perché le variabili di ambiente non sono l'approccio più sicuro. Per i test di sviluppo locali, lo strumento Secret Manager è consigliato per proteggere i dati sensibili. Per ulteriori informazioni, vedi le seguenti risorse:

Per lo sviluppo e il test locali sul lato client e sul lato server, usare lo strumento Secret Manager per proteggere le credenziali sensibili.

Modello di progetto

Creare una nuova app lato Blazor server seguendo le indicazioni riportate in Strumenti per ASP.NET Core Blazor.

Dopo aver scelto il modello di app sul lato server e aver configurato il progetto, selezionare l'autenticazione dell'app in Tipo di autenticazione:

  • Nessuno (impostazione predefinita): nessuna autenticazione.
  • Account singoli: gli account utente vengono archiviati all'interno dell'app usando ASP.NET Core Identity.

Blazor Identity Interfaccia utente (singoli account)

Blazor supporta la generazione di un'interfaccia utente completa Blazorbasata su Identity quando si sceglie l'opzione di autenticazione per singoli account.

Il Blazor Web App codice dello scaffolding del Identity modello per un database di SQL Server. La versione della riga di comando usa SQLite e include un database SQLite per Identity.

Il modello:

  • Supporta scenari di rendering interattivo lato server (SSR interattivo) e di rendering lato client con utenti autenticati.
  • Aggiunge IdentityRazor componenti e logica correlata per le attività di autenticazione di routine, ad esempio l'accesso e l'uscita degli utenti. I Identity componenti supportano anche funzionalità avanzate Identity , ad esempio la conferma dell'account e il ripristino delle password e l'autenticazione a più fattori usando un'app di terze parti. Si noti che i componenti stessi non supportano l'interattività Identity .
  • Aggiunge i Identitypacchetti e le dipendenze correlati a .
  • Fa riferimento ai Identity pacchetti in _Imports.razor.
  • Crea una classe utente Identity personalizzata (ApplicationUser).
  • Crea e registra un EF Core contesto di database (ApplicationDbContext).
  • Configura il routing per gli endpoint predefiniti Identity .
  • Include Identity la convalida e la logica di business.

Per esaminare i componenti del framework, accedervi nelle cartelle e della cartella nel modello di progetto (origine di riferimento).To inspect the framework's Blazor components, access them in the Identity and Pages folders of the Shared.Account

Quando si scelgono le modalità di rendering Interattivo WebAssembly o Interactive Auto, il server gestisce tutte le richieste di autenticazione e autorizzazione e i Identity componenti vengono visualizzati in modo statico sul server nel Blazor Web Appprogetto principale.

Il framework fornisce un oggetto personalizzato AuthenticationStateProvider nei progetti server e client (.Client) per il flusso dello stato di autenticazione dell'utente nel browser. Il progetto server chiama AddAuthenticationStateSerialization, mentre il progetto client chiama AddAuthenticationStateDeserialization. L'autenticazione nel server anziché nel client consente all'app di accedere allo stato di autenticazione durante la pre-esecuzione e prima dell'inizializzazione del runtime WebAssembly .NET. Le implementazioni personalizzate AuthenticationStateProvider usano il servizio Stato componente persistente (PersistentComponentState) per serializzare lo stato di autenticazione nei commenti HTML e quindi leggerlo di nuovo da WebAssembly per creare una nuova AuthenticationState istanza. Per altre informazioni, vedere la sezione Gestire lo stato di autenticazione in Blazor Web Apps .

Solo per le soluzioni Interactive Server, IdentityRevalidatingAuthenticationStateProvider (origine di riferimento) è un lato AuthenticationStateProvider server che riconvalida il timbro di sicurezza per l'utente connesso ogni 30 minuti viene connesso un circuito interattivo.

Quando si scelgono le modalità di rendering Interattivo WebAssembly o Interactive Auto, il server gestisce tutte le richieste di autenticazione e autorizzazione e i Identity componenti vengono visualizzati in modo statico sul server nel Blazor Web Appprogetto principale. Il modello di progetto include una PersistentAuthenticationStateProvider classe (origine di riferimento) nel .Client progetto per sincronizzare lo stato di autenticazione dell'utente tra il server e il browser. La classe è un'implementazione personalizzata di AuthenticationStateProvider. Il provider usa il servizio Stato componente persistente (PersistentComponentState) per prerendere lo stato di autenticazione e salvarlo in modo permanente nella pagina.

Nel progetto principale di un , Blazor Web Appil provider di stato di autenticazione è denominato IdentityRevalidatingAuthenticationStateProvider (origine di riferimento) (solo soluzioni di interattività server) o PersistingRevalidatingAuthenticationStateProvider (origine riferimento) (WebAssembly o soluzioni di interattività automatica).

Blazor Identity dipende dalle DbContext istanze non create da una factory, che è intenzionale perché DbContext è sufficiente per il rendering statico dei componenti del modello di Identity progetto senza supportare l'interattività.

Per una descrizione del modo in cui le modalità di rendering interattive globali vengono applicate aIdentity componenti diversi dall'applicazione contemporaneamente di SSR statico per i Identity componenti, vedere Blazor di rendering core.

Per altre informazioni sulla persistenza dello stato prerenderato, vedere Razor principali.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Gestire lo stato di autenticazione in Blazor Web Apps

Questa sezione si applica agli Blazor Web Appelementi che adottano:

  • Singoli account
  • Rendering lato client (CSR, interattività basata su WebAssembly).

Un provider di stato di autenticazione lato client viene usato solo all'interno Blazor di e non è integrato con il sistema di autenticazione ASP.NET Core. Durante la pre-esecuzione, Blazor rispetta i metadati definiti nella pagina e usa il sistema di autenticazione ASP.NET Core per determinare se l'utente è autenticato. Quando un utente passa da una pagina a un'altra, viene usato un provider di autenticazione lato client. Quando l'utente aggiorna la pagina (ricaricamento a pagina intera), il provider di stato di autenticazione lato client non è coinvolto nella decisione di autenticazione sul server. Poiché lo stato dell'utente non è persistente dal server, qualsiasi stato di autenticazione gestito sul lato client viene perso.

Per risolvere questo problema, l'approccio migliore consiste nell'eseguire l'autenticazione all'interno del sistema di autenticazione principale ASP.NET. Il provider di stato di autenticazione lato client si occupa solo di riflettere lo stato di autenticazione dell'utente. Gli esempi di come eseguire questa operazione con i provider di stato di autenticazione sono illustrati dal Blazor Web App modello di progetto e descritti di seguito.

Nel file del Program progetto server chiamare AddAuthenticationStateSerialization, che serializza l'oggetto AuthenticationState restituito dal lato AuthenticationStateProvider server usando il servizio Stato componente persistente (PersistentComponentState):

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization();

L'API serializza solo il nome lato server e le attestazioni del ruolo per l'accesso nel browser. Per includere tutte le attestazioni, impostare su SerializeAllClaimstrue nella chiamata sul lato server a AddAuthenticationStateSerialization:

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization(
        options => options.SerializeAllClaims = true);

Nel file del progetto client (.Client) chiamare Program, che aggiunge un oggetto AddAuthenticationStateDeserialization in cui AuthenticationStateProvider viene deserializzato dal server tramite AuthenticationState e il AuthenticationStateData Stato componente persistente ().PersistentComponentState Deve essere presente una chiamata corrispondente a AddAuthenticationStateSerialization nel progetto server.

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
  • PersistingRevalidatingAuthenticationStateProvider (origine di riferimento): per Blazor Web Apps che adottano il rendering interattivo lato server (SSR interattivo) e il rendering lato client (CSR). Si tratta di un lato AuthenticationStateProvider server che riconvalida il timbro di sicurezza per l'utente connesso ogni 30 minuti che un circuito interattivo è connesso. Usa anche il servizio Stato componente persistente per eseguire il flusso dello stato di autenticazione al client, che viene quindi corretto per la durata della richiesta di firma del certificato.

  • PersistingServerAuthenticationStateProvider (origine di riferimento): per Blazor Web Apps che adotta solo CSR. Si tratta di un lato AuthenticationStateProvider server che usa il servizio Stato componente persistente per trasferire lo stato di autenticazione al client, che viene quindi risolto per la durata della richiesta di firma del certificato.

  • PersistentAuthenticationStateProvider (origine di riferimento): per Blazor Web Appl'adozione di CSR. Si tratta di un lato AuthenticationStateProvider client che determina lo stato di autenticazione dell'utente cercando i dati salvati in modo permanente nella pagina quando è stato eseguito il rendering nel server. Questo stato di autenticazione è fisso per la durata della richiesta di firma del certificato. Se l'utente deve accedere o disconnettersi, è necessario ricaricare a pagina intera. Questo fornisce solo un nome utente e un messaggio di posta elettronica a scopo di visualizzazione. Non include token che eseguono l'autenticazione al server quando effettuano richieste successive, che vengono gestite separatamente usando un cookie oggetto incluso nelle HttpClient richieste al server.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Eseguire lo scaffolding di Identity

Per altre informazioni sullo scaffolding Identity in un'app lato Blazor server, vedere Scaffolding Identity nei progetti ASP.NET Core.

Eseguire lo scaffolding Identity in un'app lato Blazor server:

Attestazioni e token aggiuntivi da provider esterni

Per archiviare attestazioni aggiuntive da provider esterni, vedere Rendere persistenti attestazioni e token aggiuntivi da provider esterni in ASP.NET Core.

Servizio app di Azure in Linux con Identity Server

Specificare l'autorità emittente in modo esplicito durante la distribuzione in Servizio app di Azure in Linux con Identity Server. Per altre informazioni, vedere Usare Identity per proteggere un back-end dell'API Web per le applicazioni a pagina singola.

AuthenticationStateProvider Inserimento per i servizi con ambito a un componente

Non tentare di risolvere AuthenticationStateProvider all'interno di un ambito personalizzato perché comporta la creazione di una nuova istanza di AuthenticationStateProvider che non è inizializzata correttamente.

Per accedere all'oggetto AuthenticationStateProvider all'interno di un servizio con ambito a un componente, inserire AuthenticationStateProvider con la@injectdirettiva o l'attributo [Inject] e passarlo al servizio come parametro. Questo approccio garantisce che venga usata l'istanza corretta e inizializzata di per ogni istanza dell'app AuthenticationStateProvider utente.

ExampleService.cs:

public class ExampleService
{
    public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
    {
        var authState = await authStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            return $"{user.Identity.Name} is authenticated.";
        }
        else
        {
            return "The user is NOT authenticated.";
        }
    }
}

Registrare il servizio come ambito. In un'app lato Blazor server, i servizi con ambito hanno una durata uguale alla durata del circuito di connessione client.

Nel file Program:

builder.Services.AddScoped<ExampleService>();

In Startup.ConfigureServices di Startup.cs:

services.AddScoped<ExampleService>();

Nel componente InjectAuthStateProvider seguente:

InjectAuthStateProvider.razor:

@page "/inject-auth-state-provider"
@inherits OwningComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}

Per altre informazioni, vedere le indicazioni su OwningComponentBase in ASP.NET Blazor core dependency injection.

Visualizzazione di contenuto non autorizzato durante la pre-gestione con un oggetto personalizzato AuthenticationStateProvider

Per evitare di visualizzare contenuto non autorizzato, ad esempio contenuto in un componente, durante la pre-gestione con un oggetto personalizzatoAuthorizeView, adottare AuthenticationStateProvider degli approcci seguenti:

  • Disabilita prerendering: indicare la modalità di rendering con il prerender parametro impostato su false al componente di livello più alto nella gerarchia dei componenti dell'app che non è un componente radice.

    Nota

    Rendere interattivo un componente radice, ad esempio il App componente, non è supportato. Di conseguenza, il prerendering non può essere disabilitato direttamente dal App componente.

    Per le app basate sul modello di Blazor Web App progetto, il prerendering viene in genere disabilitato in cui il Routes componente viene usato nel App componente (Components/App.razor) :

    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    Disabilitare anche la prerendering per il HeadOutlet componente:

    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    È anche possibile controllare in modo selettivo la modalità di rendering applicata all'istanza del Routes componente. Ad esempio, vedere Blazor di rendering core.

  • Disabilita prerendering: aprire il _Host.cshtml file e modificare l'attributo dell'helperrender-modetag del componente in :Server

    <component type="typeof(App)" render-mode="Server" />
    
  • Autenticare l'utente nel server prima dell'avvio dell'app: per adottare questo approccio, l'app deve rispondere alla richiesta iniziale di un utente con la pagina o la Identityvisualizzazione di accesso basata su e impedire le richieste agli endpoint fino a Blazor quando non vengono autenticate. Per altre informazioni, vedere Creare un'app ASP.NET Core con i dati utente protetti dall'autorizzazione. Dopo l'autenticazione, il contenuto non autorizzato nei componenti prerenderati Razor viene visualizzato solo quando l'utente non è realmente autorizzato a visualizzare il contenuto.

Gestione dello stato utente

Nonostante la parola "state" nel nome, AuthenticationStateProvider non è per l'archiviazione dello stato utente generale. AuthenticationStateProvider indica solo lo stato di autenticazione dell'utente all'app, se hanno eseguito l'accesso all'app e chi ha eseguito l'accesso.

L'autenticazione usa la stessa autenticazione ASP.NET Core Identity delle Razor app Pages e MVC. Lo stato utente archiviato per i flussi ASP.NET Core Identity a Blazor senza aggiungere codice aggiuntivo all'app. Seguire le indicazioni riportate negli articoli e nelle esercitazioni di base di ASP.NET Identity per rendere effettive le Identity funzionalità nelle Blazor parti dell'app.

Per indicazioni sulla gestione generale dello stato all'esterno di ASP.NET CoreIdentity, vedere Blazor dello stato core.

Astrazioni di sicurezza aggiuntive

Due astrazioni aggiuntive partecipano alla gestione dello stato di autenticazione:

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Gestione dello stato di autenticazione alla disconnessa

Il lato Blazor server mantiene lo stato di autenticazione utente per la durata del circuito, incluse le schede del browser. Per disconnettere in modo proattivo un utente tra le schede del browser quando l'utente si disconnette in una scheda, è necessario implementare un'origine RevalidatingServerAuthenticationStateProviderdi riferimento con un breve RevalidationInterval.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Durata della validità dell'URL di reindirizzamento temporaneo

Questa sezione si applica a Blazor Web Apps.

Usare l'opzione RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration per ottenere o impostare la durata di ASP.NET validità di Core Data Protection per gli URL di reindirizzamento temporanei generati dal Blazor rendering lato server. Questi vengono usati solo temporaneamente, quindi la durata deve essere sufficiente per consentire a un client di ricevere l'URL e iniziare a spostarsi. Tuttavia, dovrebbe anche essere abbastanza lungo per consentire l'asimmetria dell'orologio tra i server. Il valore predefinito è cinque minuti.

Nell'esempio seguente il valore viene esteso a sette minuti:

builder.Services.AddRazorComponents(options => 
    options.TemporaryRedirectionUrlValidityDuration = 
        TimeSpan.FromMinutes(7));

Autenticazione lato client Blazor

Nelle app sul lato client, i controlli di autenticazione lato Blazor client possono essere ignorati perché tutto il codice lato client può essere modificato dagli utenti. Lo stesso vale per tutte le tecnologie delle app lato client, inclusi framework SPA JavaScript e app native per qualsiasi sistema operativo.

Aggiungere quanto segue:

Per gestire l'autenticazione, usare il servizio predefinito o personalizzato AuthenticationStateProvider .

Per altre informazioni sull'autenticazione lato client, vedere Secure ASP.NET Core Blazor WebAssembly.

Servizio AuthenticationStateProvider

AuthenticationStateProvider è il servizio sottostante usato dal AuthorizeView componente e dai servizi di autenticazione a catena per ottenere lo stato di autenticazione per un utente.

AuthenticationStateProviderè il servizio sottostante usato dal componente e AuthorizeView dal CascadingAuthenticationState componente per ottenere lo stato di autenticazione per un utente.

In genere non si usa AuthenticationStateProvider direttamente. Usare gli approcci con il componente AuthorizeView oppure Task<AuthenticationState> descritti più avanti in questo articolo. Lo svantaggio principale dell'uso diretto di AuthenticationStateProvider è che il componente non riceve alcuna notifica automaticamente se i dati relativi allo stato di autenticazione sottostanti cambiano.

Per implementare un oggetto personalizzato AuthenticationStateProvider, vedere ASP.NET stato di autenticazione core Blazor , che include indicazioni sull'implementazione delle notifiche di modifica dello stato di autenticazione utente.

Ottenere i dati dell'entità di attestazione di un utente

Il AuthenticationStateProvider servizio può fornire i dati dell'utente ClaimsPrincipal corrente, come illustrato nell'esempio seguente.

ClaimsPrincipalData.razor:

@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Any())
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Nell'esempio precedente:

  • ClaimsPrincipal.Claims restituisce le attestazioni dell'utente (claims) per la visualizzazione nell'interfaccia utente.
  • Riga che ottiene il cognome dell'utente (surname) con ClaimsPrincipal.FindAll un predicato per filtrare le attestazioni dell'utente.
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Any())
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Se user.Identity.IsAuthenticated è true e perché l'utente è un ClaimsPrincipal, è possibile enumerare le attestazioni e valutare l'appartenenza ai ruoli.

Per altre informazioni sull'inserimento delle dipendenze e sui servizi, vedere Inserimento delle dipendenze di ASP.NET Core Blazor e Inserimento delle dipendenze in ASP.NET Core. Per informazioni su come implementare un oggetto personalizzatoAuthenticationStateProvider, vedere Blazor di autenticazione core.

Esporre lo stato di autenticazione come un parametro a catena

Se i dati dello stato di autenticazione sono necessari per la logica procedurale, ad esempio quando si esegue un'azione attivata dall'utente, ottenere i dati dello stato di autenticazione definendo un parametro a catena di tipoTask<AuthenticationState> , come illustrato nell'esempio seguente.

CascadeAuthState.razor:

@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}
@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}

Se user.Identity.IsAuthenticated è true, è possibile enumerare le attestazioni e valutare l'appartenenza ai ruoli.

Configurare il Task<AuthenticationState> parametro a catena usando i AuthorizeRouteView servizi di stato di autenticazione a catena e .

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app include AuthorizeRouteView e la chiamata a AddCascadingAuthenticationState illustrata nell'esempio seguente. Un'app lato Blazor client include anche le registrazioni del servizio necessarie. Altre informazioni vengono visualizzate nella sezione Personalizzare il contenuto non autorizzato con il Router componente .

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

Program Nel file registrare i servizi di stato di autenticazione a catena:

builder.Services.AddCascadingAuthenticationState();

Configurare il Task<AuthenticationState>parametro a catena usando i AuthorizeRouteView componenti e .CascadingAuthenticationState

Quando si crea un'app Blazor da uno dei Blazor modelli di progetto con autenticazione abilitata, l'app include i AuthorizeRouteView componenti e CascadingAuthenticationState illustrati nell'esempio seguente. Un'app lato Blazor client include anche le registrazioni del servizio necessarie. Altre informazioni vengono visualizzate nella sezione Personalizzare il contenuto non autorizzato con il Router componente .

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

Nota

Con la versione di ASP.NET Core 5.0.1 e per eventuali versioni 5.x aggiuntive, il componente Router include il parametro PreferExactMatches impostato su @true. Per altre informazioni, vedere Eseguire la migrazione da ASP.NET Core 3.1 a 5.0.

In un'app sul lato Blazor client aggiungere i servizi di autorizzazione al Program file:

builder.Services.AddAuthorizationCore();

In un'app sul lato Blazor client aggiungere opzioni e servizi di autorizzazione al Program file:

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

In un'app sul lato Blazor server i servizi per le opzioni e l'autorizzazione sono già presenti, quindi non sono necessari altri passaggi.

Autorizzazione

Dopo l'autenticazione di un utente, vengono applicate le regole di autorizzazione per controllare le operazioni consentite per un utente.

L'accesso viene in genere concesso o negato in base alle condizioni seguenti:

  • L'utente è autenticato (ha eseguito l'accesso).
  • L'utente è incluso in un ruolo.
  • L'utente ha un'attestazione.
  • I criteri sono soddisfatti.

Questi concetti sono uguali a quelli validi per un'app ASP.NET Core MVC o Razor Pages. Per altre informazioni sulla sicurezza di ASP.NET Core, vedere gli articoli in Sicurezza e Identity per ASP.NET Core.

Componente AuthorizeView

Il componente AuthorizeView visualizza in modo selettivo il contenuto dell'interfaccia utente a seconda del fatto che l'utente sia autorizzato. Questo approccio è utile quando è sufficiente visualizzare i dati per l'utente e non è necessario usare la logica procedurale dell'utenteidentity.

Il componente espone una context variabile di tipo AuthenticationState (@context nella Razor sintassi), che è possibile usare per accedere alle informazioni sull'utente connesso:

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>

È anche possibile fornire contenuto diverso per la visualizzazione se l'utente non è autorizzato con una combinazione dei Authorized parametri e NotAuthorized :

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
        <p><button @onclick="HandleClick">Authorized Only Button</button></p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    private void HandleClick() { ... }
}

Anche se il AuthorizeView componente controlla la visibilità degli elementi in base allo stato di autorizzazione dell'utente, non impone la sicurezza sul gestore eventi stesso. Nell'esempio precedente il HandleClick metodo è associato solo a un pulsante visibile agli utenti autorizzati, ma nulla impedisce di richiamare questo metodo da altre posizioni. Per garantire la sicurezza a livello di metodo, implementare logica di autorizzazione aggiuntiva all'interno del gestore stesso o nell'API pertinente.

Razor i componenti di Blazor Web Apps non visualizzano <NotAuthorized> mai il contenuto quando l'autorizzazione non riesce sul lato server durante il rendering statico lato server (SSR statico). Il lato server ASP.NET core pipeline elabora l'autorizzazione nel server. Usare tecniche lato server per gestire le richieste non autorizzate. Per altre informazioni, vedere Blazor di rendering core.

Avviso

Il markup e i metodi lato client associati a un AuthorizeView oggetto sono protetti solo dalla visualizzazione e dall'esecuzione nell'interfaccia utente sottoposta a rendering nelle app lato Blazor client. Per proteggere il contenuto autorizzato e i metodi sicuri sul lato Blazorclient, il contenuto viene in genere fornito da una chiamata API Web sicura e autorizzata a un'API server e mai archiviata nell'app. Per altre informazioni, vedere Blazor ASP.NET Core e Blazor WebAssembly core.

Il contenuto di Authorized e NotAuthorized può includere elementi arbitrari, ad esempio altri componenti interattivi.

Le condizioni di autorizzazione, ad esempio i ruoli o i criteri che consentono di controllare le opzioni dell'interfaccia utente o l'accesso, sono presentate nella sezione Autorizzazione.

Se le condizioni di autorizzazione non vengono specificate, AuthorizeView usa un criterio predefinito:

  • Gli utenti autenticati (connessi) sono autorizzati.
  • Gli utenti non autenticati (disconnessi) non sono autorizzati.

Il componente AuthorizeView può essere usato nel componente NavMenu (Shared/NavMenu.razor) per visualizzare un componente NavLink (NavLink), ma si noti che questo approccio rimuove solo l'elemento di elenco dall'output di cui è stato eseguito il rendering. Non impedisce all'utente di passare al componente. Implementare l'autorizzazione separatamente nel componente di destinazione.

Autorizzazione basata sui ruoli e basata sui criteri

Il componente AuthorizeView supporta l'autorizzazione basata sui ruoli oppure basata sui criteri.

Per l'autorizzazione basata sui ruoli, usare il Roles parametro . Nell'esempio seguente, l'utente deve avere un'attestazione del ruolo per i Admin ruoli o Superuser :

<AuthorizeView Roles="Admin, Superuser">
    <p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>

Per richiedere che un utente disponga di attestazioni di ruolo e AdminSuperuser , annidare AuthorizeView i componenti:

<AuthorizeView Roles="Admin">
    <p>User: @context.User</p>
    <p>You have the 'Admin' role claim.</p>
    <AuthorizeView Roles="Superuser" Context="innerContext">
        <p>User: @innerContext.User</p>
        <p>You have both 'Admin' and 'Superuser' role claims.</p>
    </AuthorizeView>
</AuthorizeView>

Il codice precedente stabilisce un oggetto Context per il componente interno AuthorizeView per evitare un AuthenticationState conflitto di contesto. L'accesso AuthenticationState al contesto viene eseguito nell'esterno AuthorizeView con l'approccio standard per l'accesso al contesto (@context.User). Si accede al contesto interno AuthorizeView con il contesto denominato innerContext (@innerContext.User).

Per altre informazioni, incluse indicazioni sulla configurazione, vedere Autorizzazione basata sui ruoli in ASP.NET Core.

Per l'autorizzazione basata su criteri, usare il Policy parametro con un singolo nome di criteri:

<AuthorizeView Policy="Over21">
    <p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>

Per gestire il caso in cui l'utente deve soddisfare uno dei diversi criteri, creare un criterio che conferma che l'utente soddisfi altri criteri.

Per gestire il caso in cui l'utente deve soddisfare contemporaneamente diversi criteri, adottare uno degli approcci seguenti:

  • Creare un criterio per AuthorizeView che conferma che l'utente soddisfi diversi altri criteri.

  • Annidare i criteri in più AuthorizeView componenti:

    <AuthorizeView Policy="Over21">
        <AuthorizeView Policy="LivesInCalifornia">
            <p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
        </AuthorizeView>
    </AuthorizeView>
    

L'autorizzazione basata sulle attestazioni è un caso speciale di autorizzazione basata su criteri. Ad esempio, è possibile definire un criterio che richiede che gli utenti abbiano una determinata attestazione. Per altre informazioni, vedere Autorizzazione basata sui criteri in ASP.NET Core.

Se non viene specificato né RolesPolicy , AuthorizeView usa i criteri predefiniti:

  • Gli utenti autenticati (connessi) sono autorizzati.
  • Gli utenti non autenticati (disconnessi) non sono autorizzati.

Poiché i confronti tra stringhe .NET fanno distinzione tra maiuscole e minuscole, anche i nomi dei criteri e dei ruoli corrispondenti fanno distinzione tra maiuscole e minuscole. Ad esempio, Admin (maiuscolo A) non viene considerato come lo stesso ruolo di admin (minuscolo a).

Il caso Pascal viene in genere usato per i nomi dei ruoli e dei criteri ,ad esempio BillingAdministrator, ma l'uso del caso Pascal non è un requisito rigoroso. Sono consentiti diversi schemi di maiuscole e minuscole, come il case camel, il kebab case e il caso serpente. L'uso di spazi nei nomi di ruoli e criteri è insolito ma consentito dal framework. Ad esempio, billing administrator è un formato insolito di ruoli o nomi di criteri nelle app .NET, ma si tratta di un ruolo o un nome di criteri valido.

Contenuto visualizzato durante l'autenticazione asincrona

Blazor consente di determinare lo stato di autenticazione in modo asincrono. Lo scenario principale per questo approccio è nelle app lato Blazor client che effettuano una richiesta a un endpoint esterno per l'autenticazione.

Mentre l'autenticazione è in corso, AuthorizeView non visualizza alcun contenuto. Per visualizzare il contenuto durante l'autenticazione, assegnare il contenuto al Authorizing parametro :

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <Authorizing>
        <p>You can only see this content while authentication is in progress.</p>
    </Authorizing>
</AuthorizeView>

Questo approccio non è in genere applicabile alle app lato Blazor server. Le app sul lato Blazor server conoscono lo stato di autenticazione non appena viene stabilito lo stato. Authorizing il contenuto può essere fornito nel componente di AuthorizeView un'app, ma il contenuto non viene mai visualizzato.

Attributo [Authorize]

L'attributo [Authorize] è disponibile nei Razor componenti:

@page "/"
@attribute [Authorize]

You can only see this if you're signed in.

Importante

Usare [Authorize] solo sui @page componenti raggiunti tramite il Blazor router. L'autorizzazione viene eseguita solo come un aspetto del routing e non per i componenti figlio di cui viene eseguito il rendering all'interno di una pagina. Per autorizzare la visualizzazione di parti specifiche all'interno di una pagina, usare invece AuthorizeView.

L'attributo [Authorize] supporta anche l'autorizzazione basata sui ruoli o basata sui criteri. Per l'autorizzazione basata sui ruoli, usare il parametro Roles:

@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]

<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>

Per l'autorizzazione basata sui criteri, usare il parametro Policy:

@page "/"
@attribute [Authorize(Policy = "Over21")]

<p>You can only see this if you satisfy the 'Over21' policy.</p>

Se non viene specificato né RolesPolicy , [Authorize] usa i criteri predefiniti:

  • Gli utenti autenticati (connessi) sono autorizzati.
  • Gli utenti non autenticati (disconnessi) non sono autorizzati.

Quando l'utente non è autorizzato e se l'app non personalizza il contenuto non autorizzato con il Router componente, il framework visualizza automaticamente il messaggio di fallback seguente:

Not authorized.

Autorizzazione delle risorse

Per autorizzare gli utenti per le risorse, passare i dati di route della richiesta al parametro Resource di AuthorizeRouteView.

Router.Found Nel contenuto di una route richiesta:

<AuthorizeRouteView Resource="routeData" RouteData="routeData" 
    DefaultLayout="typeof(MainLayout)" />

Per altre informazioni sul modo in cui i dati sullo stato di autorizzazione vengono passati e usati nella logica procedurale, vedere la sezione Esporre lo stato di autenticazione come parametro a catena.

Quando AuthorizeRouteView riceve i dati di route per la risorsa, i criteri di autorizzazione hanno accesso a RouteData.PageType e RouteData.RouteValues che consentono alla logica personalizzata di prendere decisioni per l'autorizzazione.

Nell'esempio seguente viene creato un criterio EditUser in AuthorizationOptions per la configurazione del servizio di autorizzazione dell'app (AddAuthorizationCore) con la logica seguente:

  • Determinare se esiste un valore di route con una chiave id. Se la chiave esiste, il valore della route viene archiviato in value.
  • In una variabile denominata id, archiviare value come stringa o impostare un valore stringa vuoto (string.Empty).
  • Se id non è una stringa vuota, confermare che il criterio è soddisfatto (restituire true) se il valore della stringa inizia con EMP. In caso contrario, confermare che il criterio non è stato soddisfatto (restituire false).

Nel file Program:

  • Aggiungere gli spazi dei nomi per Microsoft.AspNetCore.Components e System.Linq:

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • Aggiungere il criterio:

    options.AddPolicy("EditUser", policy =>
        policy.RequireAssertion(context =>
        {
            if (context.Resource is RouteData rd)
            {
                var routeValue = rd.RouteValues.TryGetValue("id", out var value);
                var id = Convert.ToString(value, 
                    System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty;
    
                if (!string.IsNullOrEmpty(id))
                {
                    return id.StartsWith("EMP", StringComparison.InvariantCulture);
                }
            }
    
            return false;
        })
    );
    

L'esempio precedente è un criterio di autorizzazione molto semplificato, usato semplicemente per una dimostrazione del concetto con un esempio funzionante. Per altre informazioni sulla creazione e la configurazione dei criteri di autorizzazione, vedere Autorizzazione basata su criteri in ASP.NET Core.

Nel componente EditUser seguente la risorsa in /users/{id}/edit ha un parametro di route per l'identificatore dell'utente ({id}). Il componente usa il criterio di autorizzazione EditUser precedente per determinare se il valore della route per id inizia con EMP. Se inizia id con EMP, il criterio è soddisfatto e l'accesso al componente viene autorizzato. Se id inizia con un valore diverso da EMP o se id è una stringa vuota, il criterio non è soddisfatto e il componente non viene caricato.

EditUser.razor:

@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

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

Personalizzare il contenuto non autorizzato con il Router componente

Il componente Router, insieme al componente AuthorizeRouteView, consente all'app di specificare il contenuto personalizzato se:

  • L'utente non supera una condizione [Authorize] applicata al componente. Viene visualizzato il markup dell'elemento <NotAuthorized>. L'attributo [Authorize] viene presentato nella sezione Attributo [Authorize].
  • L'autorizzazione asincrona è in corso, il che significa in genere che il processo di autenticazione dell'utente è in corso. Viene visualizzato il markup dell'elemento <Authorizing>.

Importante

Blazor le funzionalità del router che visualizzano <NotAuthorized> e <NotFound> contenuto non sono operative durante il rendering statico lato server (SSR statico) perché l'elaborazione delle richieste è interamente gestita da ASP.NET elaborazione delle richieste di pipeline middleware core e Razor i componenti non vengono sottoposti a rendering per richieste non autorizzate o non valide. Usare tecniche lato server per gestire richieste non autorizzate e non valide durante ssr statici. Per altre informazioni, vedere Blazor di rendering core.

<Router ...>
    <Found ...>
        <AuthorizeRouteView ...>
            <NotAuthorized>
                ...
            </NotAuthorized>
            <Authorizing>
                ...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
</Router>

Il contenuto di Authorized e NotAuthorized può includere elementi arbitrari, ad esempio altri componenti interattivi.

Nota

Il precedente richiede la registrazione dei servizi di stato di autenticazione a catena nel file dell'app Program :

builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView ...>
                <NotAuthorized>
                    ...
                </NotAuthorized>
                <Authorizing>
                    ...
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

Il contenuto di NotFound, Authorized e NotAuthorized può includere elementi arbitrari, ad esempio altri componenti interattivi.

Se NotAuthorized il contenuto non è specificato, AuthorizeRouteView usa il messaggio di fallback seguente:

Not authorized.

Un'app creata dal Blazor WebAssembly modello di progetto con l'autenticazione abilitata include un RedirectToLogin componente posizionato nel <NotAuthorized> contenuto del Router componente. Quando un utente non è autenticato (context.User.Identity?.IsAuthenticated != true), il RedirectToLogin componente reindirizza il browser all'endpoint per l'autenticazione authentication/login . L'utente viene restituito all'URL richiesto dopo l'autenticazione con il identity provider.

Logica procedurale

Se l'app deve controllare le regole di autorizzazione come parte della logica procedurale, usare un parametro a catena di tipo Task<AuthenticationState> per ottenere il ClaimsPrincipal dell'utente. Task< AuthenticationState > può essere combinato con altri servizi, ad esempio IAuthorizationService, per valutare i criteri.

Nell'esempio seguente :

  • user.Identity.IsAuthenticated Esegue il codice per gli utenti autenticati (connessi).
  • user.IsInRole("admin") Esegue il codice per gli utenti nel ruolo 'Admin'.
  • Esegue (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded il codice per gli utenti che soddisfano i criteri 'content-editor'.

Un'app lato Blazor server include gli spazi dei nomi appropriati quando viene creato dal modello di progetto. In un'app sul lato Blazor client verificare la presenza degli Microsoft.AspNetCore.Authorization spazi dei nomi e Microsoft.AspNetCore.Components.Authorization nel componente o nel file dell'app _Imports.razor :

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

ProceduralLogic.razor:

@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}

Risolvere gli errori

Errori comuni:

  • Per l'autorizzazione è richiesto un parametro a catena di tipo Task<AuthenticationState>. Si consideri l'uso di CascadingAuthenticationState per fornirlo.

  • Valore null ricevuto per authenticationStateTask

È probabile che il progetto non sia stato creato usando un modello lato Blazor server con l'autenticazione abilitata.

In .NET 7 o versioni precedenti eseguire il wrapping di una <CascadingAuthenticationState> parte dell'albero dell'interfaccia utente, ad esempio intorno al Blazor router:

<CascadingAuthenticationState>
    <Router ...>
        ...
    </Router>
</CascadingAuthenticationState>

In .NET 8 o versione successiva non usare il CascadingAuthenticationState componente :

- <CascadingAuthenticationState>
      <Router ...>
          ...
      </Router>
- </CascadingAuthenticationState>

Aggiungere invece servizi di stato di autenticazione a catena alla raccolta di servizi nel Program file:

builder.Services.AddCascadingAuthenticationState();

Il CascadingAuthenticationState componente (.NET 7 o versioni precedenti) o i servizi forniti da AddCascadingAuthenticationState (.NET 8 o versione successiva) fornisce il Task<AuthenticationState> parametro a catena, che a sua volta riceve dal servizio di inserimento delle dipendenze sottostante.AuthenticationStateProvider

Informazioni personali (PII)

Microsoft usa la definizione del GDPR per i "dati personali" (GDPR 4.1) quando la documentazione illustra le informazioni personali.

PiI fa riferimento a qualsiasi informazione relativa a una persona fisica identificata o identificabile. Una persona fisica identificabile è una persona che può essere identificata, direttamente o indirettamente, con uno dei seguenti elementi:

  • Nome
  • Numero di identificazione
  • Coordinate della posizione
  • Identificatore online
  • Altri fattori specifici
    • Computer fisico
    • Fisiologico
    • Genetico
    • Mentale (psicologico)
    • Economico
    • Cultural
    • Sociale identity

Risorse aggiuntive