Partager via


Authentification et autorisation avec ASP.NET Core Blazor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 9 de cet article.

Cet article décrit la prise en charge d’ASP.NET Core pour la configuration et la gestion de la sécurité dans les applications Blazor.

Blazor utilise les mécanismes d’authentification ASP.NET Core existants pour établir l’identity de l’utilisateur. Le mécanisme exact dépend de la façon dont l’application Blazor est hébergée, côté serveur ou côté client.

Les scénarios de sécurité diffèrent entre le code d’autorisation s’exécutant côté serveur et celui qui s’exécute côté client dans les applications Blazor. Pour le code d’autorisation qui s’exécute sur le serveur, les vérifications d’autorisation sont en mesure d’appliquer des règles d’accès pour des zones de l’application et des composants. Comme l’exécution du code côté client peut être falsifiée, vous n’avez pas la certitude que le code d’autorisation s’exécutant sur le client va appliquer absolument des règles d’accès ou contrôler l’affichage du contenu côté client.

Si l’application de la règle d’autorisation doit être garantie, n’implémentez pas les vérifications d’autorisation dans le code côté client. Créez une Blazor Web App qui s’appuie seulement sur le rendu côté serveur pour les vérifications d’autorisation et l’application des règles.

Si l’application des règles d’autorisation et la sécurité des données et du code doivent être garanties, ne développez pas une application côté client. Créez une application Blazor Server.

Les conventions d’autorisation Razor Pages ne s’appliquent pas aux composants Razor routables. Si un composant Razor non routable est incorporé dans une page d’une application Pages Razor, les conventions d’autorisation de la page affectent indirectement le composant Razor ainsi que le rest du contenu de la page.

ASP.NET Core Identity est conçu pour fonctionner dans le contexte de la communication des requêtes et des réponses HTTP, qui n’est généralement pas le modèle de communication client-serveur de l’application Blazor. Les applications ASP.NET Core qui utilisent ASP.NET Core Identity pour la gestion des utilisateurs doivent utiliser Razor Pages plutôt que les composants Razor pour l’interface utilisateur en rapport avec Identity, notamment pour l’inscription des utilisateurs, la connexion, la déconnexion et d’autres tâches de gestion des utilisateurs. La génération de composants Razor qui gèrent directement des tâches Identity est possible pour plusieurs scénarios, mais elle n’est pas recommandée ou prise en charge par Microsoft.

Les abstractions ASP.NET Core, telles que SignInManager<TUser> et UserManager<TUser>, ne sont pas prises en charge dans les composants Razor. Pour plus d’informations sur l’utilisation d’ASP.NET Core Identity avec Blazor, consultez Générer automatiquement des modèles ASP.NET Core Identity dans une application Blazor coté serveur .

Remarque

Les exemples de code de cet article adoptent les types référence null (NRT) et l’analyse statique de l’état null du compilateur .NET, qui sont pris en charge dans ASP.NET Core dans .NET 6 ou une version ultérieure. Lorsque vous ciblez ASP.NET Core 5.0 ou version antérieure, supprimez la désignation de type nul (?) des exemples de cet article.

Maintenir en toute sécurité les données sensibles et les informations d’identification

Ne stockez pas les secrets d’application, les chaîne de connexion s, les informations d’identification, les mots de passe, les numéros d’identification personnels (PIN), le code .NET/C# privé ou les clés/jetons privés dans le code côté client, qui est toujours non sécurisé. Le code côté Blazor client doit accéder aux services et bases de données sécurisés via une API web sécurisée que vous contrôlez.

Dans les environnements de test/intermédiaire et de production, le code côté Blazor serveur et les API web doivent utiliser des flux d’authentification sécurisés qui évitent de conserver les informations d’identification dans le code du projet ou les fichiers de configuration. En dehors des tests de développement locaux, nous vous recommandons d’éviter l’utilisation de variables d’environnement pour stocker des données sensibles, car les variables d’environnement ne sont pas l’approche la plus sécurisée. Pour les tests de développement locaux, l’outil Secret Manager est recommandé pour sécuriser les données sensibles. Pour plus d’informations, consultez les ressources suivantes :

Pour le développement et les tests locaux côté client et côté serveur, utilisez l’outil Gestionnaire de secrets pour sécuriser les informations d’identification sensibles.

Identités managées pour les services Microsoft Azure

Pour les services Microsoft Azure, nous vous recommandons d’utiliser des identités managées. Les identités managées offrent un moyen sécurisé de s’authentifier auprès des services Azure sans stocker d’informations d’identification dans le code de l’application. Pour plus d’informations, consultez les ressources suivantes :

Prise en charge d’Antiforgery

Le modèle Blazor :

Le composant AntiforgeryToken affiche un jeton anti-falsification en tant que champ masqué, et ce composant est automatiquement ajouté aux instances de formulaire (EditForm). Pour plus d’informations, consultez Vue d’ensemble des formulaires Blazor ASP.NET Core.

Le service AntiforgeryStateProvider fournit un accès à un jeton anti-falsification associé à la session active. Injectez le service et appelez sa méthode GetAntiforgeryToken() pour obtenir le AntiforgeryRequestToken actuel. Pour plus d’informations, consultez Appeler une API web à partir d’une application Blazor ASP.NET Core.

Blazor stocke les jetons de requête dans l’état du composant, ce qui garantit que les jetons anti-falsification sont disponibles pour les composants interactifs, même s’ils n’ont pas accès à la requête.

Remarque

L’atténuation Antiforgery n’est requise que lors de l’envoi de données de formulaire au serveur encodé en tant que application/x-www-form-urlencoded, multipart/form-data ou text/plain, étant donné qu’il s’agit des seulstypes de chiffrement de formulaire valides.

Pour plus d’informations, consultez les ressources suivantes :

Authentification Blazor côté serveur

Les applications Blazor côté serveur sont configurées pour la sécurité de la même manière que les applications ASP.NET Core. Pour plus d’informations, consultez les articles relevant des rubriques de sécurité ASP.NET Core.

Le contexte d’authentification est établi uniquement au démarrage de l’application, c’est-à-dire lorsque l’application se connecte d’abord au WebSocket via une SignalR connexion avec le client. L’authentification peut être basée sur un cookie ou un autre jeton du porteur, mais l’authentification est gérée via le hub SignalR et entièrement au sein du circuit. Le contexte d’authentification est conservé pendant toute la durée de vie du circuit. Les applications revalident périodiquement l’état d’authentification de l’utilisateur toutes les 30 minutes.

Si l’application doit capturer des utilisateurs pour des services personnalisés ou réagir aux mises à jour de l’utilisateur, consultez Blazor Web App de sécurité côté serveur et autres.

Blazor diffère d’une application web rendue sur serveur traditionnelle qui effectue de nouvelles requêtes HTTP avec des cookies sur chaque navigation de page. L’authentification est vérifiée pendant les événements de navigation. Toutefois, les cookies ne sont pas impliqués. Les cookies sont envoyés uniquement lors de l’envoi d’une requête HTTP à un serveur, ce qui n’est pas le cas lorsque l’utilisateur navigue dans une application Blazor. Pendant la navigation, l’état d’authentification de l’utilisateur est vérifié dans le circuit Blazor, que vous pouvez mettre à jour à tout moment sur le serveur à l’aide de l’RevalidatingAuthenticationStateProviderabstraction.

Important

La mise en œuvre d'une personnalisation NavigationManager pour obtenir la validation de l'authentification pendant la navigation n'est pas recommandée. Si l’application doit exécuter une logique d’état d’authentification personnalisée pendant la navigation, utilisez un personnalisé AuthenticationStateProvider.

Remarque

Les exemples de code de cet article adoptent les types référence null (NRT) et l’analyse statique de l’état null du compilateur .NET, qui sont pris en charge dans ASP.NET Core dans .NET 6 ou une version ultérieure. Lorsque vous ciblez ASP.NET Core 5.0 ou version antérieure, supprimez la désignation de type null (?) des exemples de cet article.

Le service AuthenticationStateProvider intégré ou personnalisé obtient des données d’état d’authentification du HttpContext.User d’ASP.NET Core. C’est ainsi que l’état d’authentification s’intègre avec les mécanismes d’authentification ASP.NET Core.

Pour plus d’informations sur l’authentification côté serveur, consultez Blazor core.

IHttpContextAccessor/HttpContext dans les composants Razor

IHttpContextAccessor doit être évité avec le rendu interactif, car il n’existe pas de HttpContext valide disponible.

IHttpContextAccessor peut être utilisé pour les composants rendus statiquement sur le serveur. Toutefois, nous vous recommandons de l’éviter si possible.

HttpContext peut être utilisé comme paramètre en cascade uniquement dans les composants racines rendus statiquement pour les tâches générales, telles que l’inspection et la modification d’en-têtes ou d’autres propriétés dans le composant App (Components/App.razor). La valeur est toujours null pour le rendu interactif.

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

Pour les scénarios où HttpContext est requis dans les composants interactifs, nous vous recommandons de transmettre les données via l’état du composant persistant à partir du serveur. Pour plus d’informations, consultez Blazor Web App de sécurité côté serveur et autres.

N’utilisez pas IHttpContextAccessor/HttpContext directement ou indirectement dans les composants Razor des applications Blazor côté serveur. Les applications Blazor s’exécutent en dehors du contexte de pipeline ASP.NET Core. Le HttpContext n’est pas garanti d’être disponible dans le IHttpContextAccessor, et HttpContext n’est pas garanti de conserver le contexte qui a démarré l’application Blazor.

L’approche recommandée pour passer l’état de la requête à l’application Blazor consiste à utiliser les paramètres de composant racine pendant le rendu initial de l’application. L’application peut également copier les données dans un service délimité dans l’événement de cycle de vie d’initialisation du composant racine pour une utilisation dans l’application. Pour plus d’informations, consultez Blazor Web App de sécurité côté serveur et autres.

Un aspect essentiel de la sécurité de Blazor côté serveur est que l’utilisateur attaché à un circuit donné peut être mis à jour à un moment donné après l’établissement du circuit Blazor, mais que le IHttpContextAccessorn’est pas mis à jour. Pour plus d’informations sur la résolution de cette situation avec des services personnalisés, consultez Blazor Web App de sécurité supplémentaires côté serveur core.

État partagé

Les applications Blazor côté serveur résident dans la mémoire du serveur, et plusieurs sessions d’application sont hébergées dans le même processus. Pour chaque session d’application, Blazor démarre un circuit avec sa propre étendue de conteneur d’injection de dépendances, de sorte que les services délimités sont uniques par session Blazor.

Avertissement

Nous ne recommandons pas que les applications sur le même serveur partagent un état à l’aide des services singleton, sauf si des précautions extrêmes sont prises, car cela peut introduire des vulnérabilités de sécurité, comme des fuites d’état utilisateur entre les circuits.

Vous pouvez utiliser des services singleton avec état dans les applications Blazor si elles sont spécifiquement conçues pour cela. Par exemple, l’utilisation d’un cache de mémoire singleton est acceptable, car un cache de mémoire nécessite une clé pour accéder à une entrée donnée. En supposant que les utilisateurs ne contrôlent pas les clés de cache utilisées avec le cache, l’état stocké dans le cache ne fuit pas entre les circuits.

Pour obtenir des conseils généraux sur la gestion de l’état, consultez Gestion de l’état BlazorASP.NET Core.

Sécurité côté serveur des données sensibles et des informations d’identification

Dans les environnements de test/intermédiaire et de production, le code côté Blazor serveur et les API web doivent utiliser des flux d’authentification sécurisés qui évitent de conserver les informations d’identification dans le code du projet ou les fichiers de configuration. En dehors des tests de développement locaux, nous vous recommandons d’éviter l’utilisation de variables d’environnement pour stocker des données sensibles, car les variables d’environnement ne sont pas l’approche la plus sécurisée. Pour les tests de développement locaux, l’outil Secret Manager est recommandé pour sécuriser les données sensibles. Pour plus d’informations, consultez les ressources suivantes :

Pour le développement et les tests locaux côté client et côté serveur, utilisez l’outil Gestionnaire de secrets pour sécuriser les informations d’identification sensibles.

Modèle de projet

Créez une nouvelle application côté serveur Blazor en suivant les instructions de la section Outils pour ASP.NET Core Blazor.

Après avoir choisi le modèle d'application côté serveur et configuré le projet, sélectionnez l'authentification de l'application sous Type d'authentification :

  • Aucun (valeur par défaut) : aucune authentification.
  • Comptes individuels : les comptes d’utilisateur sont stockés dans l’application à l’aide d’ASP.NET Core Identity.
  • Aucun (valeur par défaut) : aucune authentification.
  • Comptes individuels : les comptes d’utilisateur sont stockés dans l’application à l’aide d’ASP.NET Core Identity.
  • Plateforme d’identity Microsoft : pour plus d’informations, consultez Authentification et autorisation Blazor ASP.NET Core.
  • Windows : utilisez l’authentification Windows.

Interface utilisateur BlazorIdentity (comptes individuels)

Blazor prend en charge la génération d’une interface utilisateur complète basée sur Blazor de Identity lorsque vous choisissez l’option d’authentification Comptes individuels.

Le modèle Blazor Web App génère le code Identity pour une base de données SQL Server. La version en ligne de commande utilise SQLite et inclut une base de données SQLite pour Identity.

Le modèle  :

  • Prend en charge le rendu interactif côté serveur (SSR interactif) et le rendu côté client (CSR) avec des utilisateurs authentifiés.
  • Ajoute des composants IdentityRazor et une logique associée pour les tâches d’authentification de routine, telles que la connexion et la déconnexion des utilisateurs. Les composants Identity prennent également en charge les fonctionnalités Identity avancées, telles que la confirmation de compte et la récupération de mot de passe et l’authentification multifacteur à l’aide d’une application tierce. Notez que les composants Identity eux-mêmes ne prennent pas en charge l’interactivité.
  • Ajoute les packages et dépendances associés à Identity.
  • Référence les packages Identity dans _Imports.razor.
  • Crée une classe Identity d’utilisateur personnalisée (ApplicationUser).
  • Crée et inscrit un contexte de base de données EF Core (ApplicationDbContext).
  • Configure le routage pour les points de terminaison Identity intégrés.
  • Inclut la validation Identity et la logique métier.

Pour inspecter les composants Blazor de l’infrastructure Identity, accédez-y dans les dossiers Pages et Shared du dossier Account dans le modèle de projet Blazor Web App (source de référence).

Lorsque vous choisissez les modes de rendu WebAssembly interactif ou Auto interactif, le serveur gère toutes les requêtes d’authentification et d’autorisation, et les composants Identity sont rendus de manière statique sur le serveur dans le projet principal de l’Blazor Web App.

Le framework fournit un AuthenticationStateProvider personnalisé dans les projets serveur et client (.Client) pour transmettre l’état d’authentification de l’utilisateur au navigateur. Le projet serveur appelle AddAuthenticationStateSerialization, tandis que le projet client appelle AddAuthenticationStateDeserialization. L’authentification sur le serveur plutôt que sur le client permet à l’application d’accéder à l’état d’authentification pendant le prérendu et avant l’initialisation du runtime WebAssembly .NET. Les implémentations personnalisées de AuthenticationStateProvider utilisent le service État de composant persistant (PersistentComponentState) pour sérialiser l’état d’authentification dans les commentaires HTML, puis le lisent à partir de WebAssembly pour créer une instance AuthenticationState. Pour plus d’informations, consultez la section Gérer l’état d’authentification dans les Blazor Web App.

Uniquement pour les solutions de serveur interactif, IdentityRevalidatingAuthenticationStateProvider (source de référence) est un AuthenticationStateProvidercôté serveur qui revalide l’empreinte de sécurité de l’utilisateur connecté toutes les 30 minutes lorsqu’un circuit interactif est connecté.

Lorsque vous choisissez les modes de rendu WebAssembly interactif ou Auto interactif, le serveur gère toutes les requêtes d’authentification et d’autorisation, et les composants Identity sont rendus de manière statique sur le serveur dans le projet principal de l’Blazor Web App. Le modèle de projet inclut une classe PersistentAuthenticationStateProvider (source de référence) dans le projet .Client pour synchroniser l’état d’authentification de l’utilisateur entre le serveur et le navigateur. La classe est une implémentation personnalisée de AuthenticationStateProvider. Le fournisseur utilise le service État de composant persistant (PersistentComponentState) pour prérendre l’état d’authentification et le garder sur la page.

Dans le projet principal d’une Blazor Web App, le fournisseur d’état d’authentification est nommé IdentityRevalidatingAuthenticationStateProvider (source de référence) (solutions d’interactivité de serveur uniquement) ou PersistingRevalidatingAuthenticationStateProvider (source de référence) (solutions d’interactivité WebAssembly ou automatique).

BlazorIdentity dépend des instances DbContext qui ne sont pas créées par une fabrique, ce qui est intentionnel parce que DbContext suffit pour que les composants Identity du modèle de projet soient rendus de façon statique sans prendre en charge l’interactivité.

Pour obtenir une description de la façon dont les modes de rendu interactif globaux sont appliqués aux non-composantsIdentity tout en appliquant le SSR statique pour les Identity composants, consultez ASP.NET modesBlazor de rendu Core.

Pour plus d’informations sur la persistance de l’état pré-rendu, consultez Pré-rendre les composants Razor ASP.NET Core.

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Gérer l’état d’authentification dans les Blazor Web App

Cette section s’applique aux Blazor Web App qui adoptent :

  • Comptes individuels
  • Rendu côté client (CSR, interactivité basée sur WebAssembly).

Un fournisseur d’état de l’authentification côté client est utilisé uniquement dans Blazor et n’est pas intégré au système d’authentification ASP.NET Core. Lors de la prérendu, Blazor respecte les métadonnées définies sur la page et utilise le système d’authentification ASP.NET Core pour déterminer si l’utilisateur est authentifié. Lorsqu’un utilisateur va d’une page à une autre, un fournisseur d’authentification côté client est utilisé. Lorsque l’utilisateur actualise la page (actualisation complète de la page), le fournisseur d’état de l’authentification côté client n’est pas impliqué dans la décision d’authentification sur le serveur. L’état de l’utilisateur n’étant pas conservé par le serveur, tout état d’authentification géré côté client est perdu.

Pour résoudre ce problème, la meilleure approche consiste à effectuer l’authentification dans le système d’authentification ASP.NET Core. Le fournisseur d’état de l’authentification côté client ne se charge que de refléter l’état d’authentification de l’utilisateur. Les exemples d’utilisation de fournisseurs d’état d’authentification sont illustrés par le modèle de projet d’Blazor Web App et décrits ci-dessous.

Dans le fichier Program du projet serveur, appelez AddAuthenticationStateSerialization, qui sérialise le AuthenticationState retourné par le AuthenticationStateProvider côté serveur à l’aide du service État de composant persistant (PersistentComponentState) :

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

L’API sérialise uniquement le nom et les revendications de rôle côté serveur pour l’accès dans le navigateur. Pour inclure toutes les revendications, définissez SerializeAllClaims sur true dans l’appel côté serveur pour AddAuthenticationStateSerialization :

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

Dans le fichier .Client du projet client (Program), appelez AddAuthenticationStateDeserialization, ce qui permet d’ajouter un AuthenticationStateProvider où le AuthenticationState est désérialisé à partir du serveur à l’aide de AuthenticationStateData et du service État de composant persistant (PersistentComponentState). Il doit y avoir un appel correspondant à AddAuthenticationStateSerialization dans le projet serveur.

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
  • PersistingRevalidatingAuthenticationStateProvider (source de référence) : pour les Blazor Web App qui adoptent le rendu côté serveur interactif (SSR interactif) et le rendu côté client (CSR). Il s’agit d’un AuthenticationStateProvider côté serveur qui revalide l’empreinte de sécurité de l’utilisateur connecté toutes les 30 minutes lorsqu’un circuit interactif est connecté. Il utilise également le service d’état du composant persistant pour transmettre l’état d’authentification au client. Ce dernier est ensuite fixe pour la durée de vie du rendu côté client (CSR).

  • PersistingServerAuthenticationStateProvider (source de référence) : pour les Blazor Web App qui adoptent uniquement le CSR. Il s’agit d’un AuthenticationStateProvider côté serveur qui utilise le service d’état du composant persistant pour transmettre l’état d’authentification au client. Ce dernier est ensuite fixe pour la durée de vie du rendu côté client (CSR).

  • PersistentAuthenticationStateProvider (source de référence) : pour les Blazor Web App qui adoptent le CSR. Il s’agit d’un AuthenticationStateProvider côté client qui détermine l’état d’authentification de l’utilisateur en recherchant les données persistantes dans la page, lorsqu’elles ont été rendues sur le serveur. Cet état d’authentification est fixe pour la durée de vie du rendu côté client (CSR). Si l’utilisateur doit se connecter ou se déconnecter, une actualisation complète de la page est nécessaire. Cela fournit uniquement un nom d’utilisateur et un e-mail à des fins d’affichage. Il n’inclut pas les jetons qui s’authentifient auprès du serveur lors de l’exécution de requêtes ultérieures. Ces dernières sont gérées séparément à l’aide d’un cookie, inclus dans les requêtes HttpClient envoyées au serveur.

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Gérer automatiquement des modèles Identity

Pour plus d’informations sur l’échafaudage Identity dans une application Blazor côté serveur, consultez Scaffold Identity dans les projets ASP.NET Core .

Intégrez une application Identity côté serveur Blazor :

Revendications et jetons supplémentaires en provenance de fournisseurs externes

Pour stocker des revendications supplémentaires en provenance de fournisseurs externes, consultez Conserver les revendications et les jetons supplémentaires de fournisseurs externes dans ASP.NET Core.

Azure App Service sur Linux avec Identity Server

Spécifiez explicitement l’émetteur quand le déploiement a pour cible Azure App Service sur Linux avec Identity Server. Pour plus d’informations, consultez Utiliser Identity pour sécuriser un back-end d’API web pour des applications monopage.

Injectez AuthenticationStateProvider pour les services liés à un composant

N’essayez pas de résoudre AuthenticationStateProvider dans une étendue personnalisée, car cela entraîne la création d’une nouvelle instance du AuthenticationStateProvider qui n’est pas correctement initialisée.

Pour accéder au AuthenticationStateProvider dans un service délimité à un composant, injectez le AuthenticationStateProvider avec la @inject directive ou l’[Inject]attribut et passez-le au service en tant que paramètre. Cette approche garantit que l’instance correcte et initialisée du AuthenticationStateProvider est utilisée pour chaque instance d’application utilisateur.

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

Inscrivez le service comme délimité. Dans une application Blazor côté serveur, les services étendus ont une durée de vie égale à la durée du circuit de connexion client.

Dans le fichier Program :

builder.Services.AddScoped<ExampleService>();

Dans Startup.ConfigureServices de Startup.cs :

services.AddScoped<ExampleService>();

Dans le composant InjectAuthStateProvider suivant :

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

Pour plus d’informations, consultez les conseils sur OwningComponentBase dans l’injection de dépendances Blazor dans ASP.NET Core.

Affichage de contenu non autorisé lors du prérendu avec un fichier personnalisé AuthenticationStateProvider

Pour éviter d’afficher du contenu non autorisé, par exemple pour un exemple de contenu dans un AuthorizeViewcomposant, lors d’un prérendu avec un AuthenticationStateProvider personnalisé, adoptez l’une des approches suivantes :

  • Désactiver le prérendu : indiquez le mode de rendu avec le paramètre prerender défini sur false au niveau le plus élevé dans la hiérarchie des composants de l’application qui n’est pas un composant racine.

    Remarque

    Rendre un composant racine interactif, comme le composant App, n’est pas pris en charge. Par conséquent, le prérendu ne peut pas être désactivé directement par le composant App.

    Pour les applications basées sur le modèle de projet d’Blazor Web App, le prérendu est habituellement désactivé où le composant Routes est utilisé dans le composant App (Components/App.razor) :

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

    Désactivez également le pré-rendu pour le composant HeadOutlet :

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

    Vous pouvez également contrôler de manière sélective le mode de rendu appliqué à l’instance de composant Routes. Par exemple, consultez les modes de rendu Blazor ASP.NET Core.

  • Désactivez le prérendu : ouvrez le fichier _Host.cshtml et modifiez l'attribut render-mode du Component Tag Helper en Server :

    <component type="typeof(App)" render-mode="Server" />
    
  • Authentifier l'utilisateur sur le serveur avant le démarrage de l'application : pour adopter cette approche, l'application doit répondre à la requête initiale d'un utilisateur avec la page de connexion basée sur Identity- ou afficher et empêcher toute demande adressée aux points de terminaison Blazor jusqu'à ce qu'ils soient authentifiés. Pour plus d’informations, consultez Créer une application ASP.NET Core avec des données utilisateur protégées par autorisation. Après l'authentification, le contenu non autorisé dans les composants Razor pré-rendus n'est affiché que lorsque l'utilisateur n'est réellement pas autorisé à afficher le contenu.

Gestion de l'état des utilisateurs

En dépit du mot « état » dans le nom, AuthenticationStateProvider n’est pas destiné au stockage de l’état général de l’utilisateur. AuthenticationStateProvider indique uniquement l’état d’authentification de l’utilisateur par rapport à l’application, s’il est connecté à l’application et sous quel nom il est connecté.

L'authentification utilise la même authentification Identity ASP.NET Core que les applications Pages Razor et MVC. L’état utilisateur stocké pour ASP.NET Core Identity transite vers Blazor sans ajouter de code supplémentaire à l’application. Suivez les instructions fournies dans les articles et tutoriels ASP.NET Core Identity pour que les fonctionnalités Identity prennent effet dans les parties Blazor de l’application.

Pour obtenir des conseils sur la gestion générale de l’état en dehors de ASP.NET Core Identity, consultez Gestion de l’état Blazor ASP.NET Core.

Abstractions de sécurité supplémentaires

Deux abstractions supplémentaires participent à la gestion de l’état d’authentification :

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Gestion de l’état d’authentification lors de la déconnexion

Blazor côté serveur conserve l’état d’authentification utilisateur pour la durée de vie du circuit, y compris entre les onglets du navigateur. Pour déconnecter de manière proactive un utilisateur dans les onglets du navigateur lorsque l’utilisateur se déconnecte d’un onglet, vous devez implémenter RevalidatingServerAuthenticationStateProvider (source de référence) avec un court RevalidationInterval.

Remarque

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Durée de validité de l’URL de redirection temporaire

Cette section s’applique aux Blazor Web App.

Utilisez l’option RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration pour obtenir ou définir la durée de vie de la validité de la protection des données ASP.NET Core pour les URL de redirection temporaires émises par le rendu côté serveur de Blazor. Celles-ci sont utilisés temporairement : la durée de vie doit donc être suffisamment longue pour qu’un client reçoive l’URL et commence la navigation vers celle-ci. Cependant, elle doit aussi être suffisamment longue pour tenir compte des décalages d’horloge entre les serveurs. La valeur par défaut est de cinq minutes.

Dans l’exemple suivant, la valeur est étendue à sept minutes :

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

Authentification Blazor côté client

Dans les applications Blazor côté client, les vérifications d’authentification côté client peuvent être contournées, car le code côté client peut être modifié par des utilisateurs. Cela vaut également pour toutes les technologies d’application côté client, y compris les infrastructures d’application monopage JavaScript et les applications natives pour n’importe quel système d’exploitation.

Ajoutez ce qui suit :

Pour gérer l’authentification, utilisez le service AuthenticationStateProvider intégré ou personnalisé.

Pour plus d’informations sur l’authentification côté client, consultez Securiser les Blazor WebAssembly ASP.NET Core.

Service AuthenticationStateProvider

AuthenticationStateProvider est le service sous-jacent utilisé par le composant AuthorizeView et les services d’authentification en cascade pour obtenir l’état d’authentification d’un utilisateur.

AuthenticationStateProvider est le service sous-jacent utilisé par le composant AuthorizeView et le composant CascadingAuthenticationState pour obtenir l’état d’authentification d’un utilisateur.

Vous n’utilisez généralement pas AuthenticationStateProvider directement. Utilisez le composant AuthorizeView ou les approches Task<AuthenticationState> décrites plus loin dans cet article. Le principal inconvénient de l’utilisation directe de AuthenticationStateProvider est que le composant n’est pas automatiquement averti en cas de modifications de données d’état de l’authentification sous-jacente.

Pour implémenter un AuthenticationStateProvider personnalisé, consultez État d’authentification Blazor ASP.NET Core, qui inclut des conseils sur l’implémentation des notifications de modification d’état d’authentification utilisateur.

Obtenir les données du principal des revendications d’un utilisateur

Le service AuthenticationStateProvider peut fournir les données ClaimsPrincipal de l’utilisateur actuel, comme indiqué dans l’exemple suivant.

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

Dans l'exemple précédent :

  • ClaimsPrincipal.Claims retourne les revendications de l’utilisateur (claims) pour affichage dans l’interface utilisateur.
  • Ligne qui obtient les appels surname du nom de l’utilisateur (ClaimsPrincipal.FindAll) avec un prédicat pour filtrer les revendications de l’utilisateur.
@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.";
        }
    }
}

Si user.Identity.IsAuthenticated est true et parce que l’utilisateur est ClaimsPrincipal, les revendications peuvent être énumérées et l’appartenance aux rôles évaluée.

Pour plus d’informations sur l’injection de dépendances (DI) et les services, consultez Injection de dépendances ASP.NET Core Blazor et Injection de dépendances dans ASP.NET Core. Pour plus d’informations sur l’implémentation d’un AuthenticationStateProvider personnalisé, consultez État d’authentification Blazor ASP.NET Core.

Exposer l’état d’authentification comme un paramètre en cascade

Si les données d’état d’authentification sont requises pour la logique procédurale, par exemple lors d’une action déclenchée par l’utilisateur, obtenez les données d’état d’authentification en définissant un paramètre en cascade de type Task<AuthenticationState>, comme le montre l’exemple suivant.

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

Si user.Identity.IsAuthenticated est true, les revendications peuvent être énumérées et l’appartenance aux rôles évaluée.

Configurez Task<AuthenticationState>, un paramètre en cascade, en utilisant la AuthorizeRouteView et les services d’état d’authentification en cascade.

Lorsque vous créez une application Blazor à partir de l’un des modèles de projet Blazor dont l’authentification est activée, l’application contient le AuthorizeRouteView et l’appel à AddCascadingAuthenticationState présentés dans l’exemple suivant. Une application Blazor côté client inclut également les inscriptions de service requises. Des informations supplémentaires sont présentées dans la section Personnaliser le contenu non autorisé avec le composant Router.

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

Dans le fichier Program, inscrivez les services d’état d’authentification en cascade :

builder.Services.AddCascadingAuthenticationState();

Configurez Task<AuthenticationState>, un paramètre en cascade, en utilisant les composants AuthorizeRouteView etCascadingAuthenticationState.

Lorsque vous créez une application Blazor à partir de l’un des modèles de projet Blazor dont l’authentification est activée, l’application contient les composants AuthorizeRouteView etCascadingAuthenticationState présentés dans l’exemple suivant. Une application Blazor côté client inclut également les inscriptions de service requises. Des informations supplémentaires sont présentées dans la section Personnaliser le contenu non autorisé avec le composant Router.

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

Remarque

Depuis le lancement d’ASP.NET Core 5.0.1 et pour les éventuelles versions 5.x supplémentaires, le composant Router comprend le paramètre PreferExactMatches, qui est défini sur @true. Pour plus d’informations, consultez Migrer de ASP.NET Core 3.1 vers 5.0.

Dans une application Blazor côté client, ajoutez des services d’autorisation au fichier Program :

builder.Services.AddAuthorizationCore();

Dans une application Blazor côté client, ajoutez des services d’autorisation et d’options et l’autorisation au fichier Program :

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

Dans une application Blazor côté serveur, les services pour les options et l’autorisation sont déjà présents. Par conséquent, aucune étape supplémentaire n’est nécessaire.

Autorisation

Une fois qu’un utilisateur est authentifié, les règles d’autorisation sont appliquées pour contrôler ce que l’utilisateur peut faire.

L’accès est généralement accordé ou refusé selon les conditions suivantes :

  • Un utilisateur est authentifié (connecté).
  • Un utilisateur appartient à un rôle.
  • Un utilisateur a une revendication.
  • Une stratégie est satisfaite.

Tous ces concepts sont les mêmes que dans une application ASP.NET Core MVC ou Razor Pages. Pour plus d’informations sur la sécurité d’ASP.NET Core, consultez les articles sous Sécurité ASP.NET Core et Identity.

AuthorizeView (composant)

Le composant AuthorizeView affiche de manière sélective le contenu d’interface utilisateur en fonction de l’autorisation dont dispose l’utilisateur. Cette approche est utile lorsque vous devez uniquement afficher les données de l’utilisateur et que vous n’avez pas besoin d’utiliser l’identity de l’utilisateur dans la logique procédurale.

Le composant expose une variable context de type AuthenticationState (@context dans la syntaxe Razor), que vous pouvez utiliser pour accéder aux informations relatives à l’utilisateur connecté :

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

Si l’utilisateur n’est pas autorisé, vous pouvez également fournir un contenu différent à afficher en combinant les paramètres Authorized et 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() { ... }
}

Bien que le AuthorizeView composant contrôle la visibilité des éléments en fonction de l’état d’autorisation de l’utilisateur, il n’applique pas la sécurité sur le gestionnaire d’événements lui-même. Dans l’exemple précédent, la HandleClick méthode n’est associée qu’à un bouton visible par les utilisateurs autorisés, mais rien n’empêche l’appel de cette méthode à d’autres emplacements. Pour garantir la sécurité au niveau de la méthode, implémentez une logique d’autorisation supplémentaire au sein du gestionnaire lui-même ou dans l’API appropriée.

Les composants Razor des Blazor Web App n’affichent jamais de contenu <NotAuthorized> lorsque l’autorisation échoue côté serveur pendant le rendu côté serveur statique (SSR statique). Le pipeline ASP.NET Core côté serveur traite l’autorisation sur le serveur. Utilisez des techniques côté serveur pour traiter les requêtes non autorisées. Pour plus d’informations, consultez Modes de rendu ASP.NET Core Blazor.

Avertissement

Le balisage côté client et les méthodes associées à un AuthorizeView sont uniquement protégés contre l’affichage et l’exécution dans l’interface utilisateur affichée dans les applications Blazor côté client. Afin de protéger un contenu autorisé et des méthodes sécurisées dans Blazor côté client, le contenu est généralement fourni par un appel d’API web sécurisé et autorisé à une API de serveur et n’est jamais stocké dans l’application. Pour plus d’informations, consultez Appeler une API web à partir d’une application ASP.NET Core Blazor et scénarios de sécurité supplémentaires Blazor WebAssembly ASP.NET Core.

Le contenu de Authorized et de NotAuthorized peut inclure des éléments arbitraires, comme d’autres composants interactifs.

Les conditions d’autorisation, comme les rôles ou les stratégies qui contrôlent les options d’interface utilisateur ou d’accès, sont traitées dans la section Autorisation.

Si les conditions d’autorisation ne sont pas spécifiées, AuthorizeView utilise une stratégie par défaut :

  • Les utilisateurs authentifiés (connectés) sont autorisés.
  • Les utilisateurs non authentifiés (déconnectés) ne sont pas autorisés.

Le composant AuthorizeView peut être utilisé dans le composant NavMenu (Shared/NavMenu.razor) pour afficher un composant NavLink (NavLink), mais notez que cette approche supprime uniquement l’élément de liste de la sortie affichée. Elle n’empêche pas l’utilisateur d’accéder au composant. Implémentez l’autorisation séparément dans le composant de destination.

Autorisation en fonction du rôle et de la stratégie

Le composant AuthorizeView prend en charge l’autorisation basée sur le rôle et basée sur les stratégies.

Pour l’autorisation en fonction du rôle, utilisez le paramètre Roles. Dans l’exemple suivant, l’utilisateur doit avoir une revendication de rôle pour les rôles Admin ou Superuser :

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

Pour exiger qu’un utilisateur ait à la fois des revendications de rôle Admin et Superuser, imbriquez AuthorizeView composants :

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

Le code précédent établit un Context pour le composant interne AuthorizeView afin d’éviter une collision de contexte AuthenticationState. Le contexte AuthenticationState est accessible dans l’extérieur AuthorizeView avec l’approche standard pour accéder au contexte (@context.User). Le contexte est accessible dans l’intérieur AuthorizeView avec le contexte nommé innerContext (@innerContext.User).

Pour plus d’informations, notamment des conseils de configuration, consultez Autorisation basée sur les rôles dans ASP.NET Core.

Pour l’autorisation basée sur une stratégie, utilisez le Policy paramètre avec un nom de stratégie unique :

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

Pour gérer le cas où l’utilisateur doit satisfaire à une stratégie parmi d’autres, créez une stratégie qui confirme que l’utilisateur satisfait à d’autres stratégies.

Pour gérer le cas où l’utilisateur doit satisfaire plusieurs stratégies simultanément, suivez l’une des approches suivantes :

  • Créez une stratégie pour AuthorizeView qui confirme que l’utilisateur satisfait à plusieurs autres stratégies.

  • Imbriquez les stratégies dans plusieurs composants AuthorizeView :

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

L’autorisation basée sur les revendications est un cas spécial d’autorisation basée sur les stratégies. Par exemple, vous pouvez définir une stratégie qui impose aux utilisateurs d’avoir une certaine revendication. Pour plus d’informations, consultez Autorisation basée sur une stratégie dans ASP.NET Core.

Si ni Roles ni Policy n’est spécifié, AuthorizeView utilise la stratégie par défaut :

  • Les utilisateurs authentifiés (connectés) sont autorisés.
  • Les utilisateurs non authentifiés (déconnectés) ne sont pas autorisés.

Étant donné que les comparaisons de chaînes .NET sont sensibles à la casse, les noms de rôle et de stratégie correspondants sont également sensibles à la casse. Par exemple, Admin (A majuscule) n’est pas traité comme le même rôle que admin (a minuscule).

La casse Pascal est généralement utilisée pour les noms de rôles et de stratégie (par exemple, BillingAdministrator), mais son utilisation n’est pas une exigence stricte. Différents schémas de casse, tels que la case chameau, la casse kebab et la casse serpent, sont autorisés. L’utilisation d’espaces dans les noms de rôle et de stratégie est inhabituelle, mais autorisée par l’infrastructure. Par exemple, billing administrator est un format de rôle ou de nom de stratégie inhabituel dans les applications .NET, mais il s’agit d’un nom de rôle ou de stratégie valide.

Contenu affiché lors de l’authentification asynchrone

Blazor permet de déterminer l’état d’authentification de façon asynchrone. Le scénario principal de cette approche réside dans les applications Blazor côté client qui créent une requête d’authentification sur un point de terminaison externe.

Lorsque l’authentification est en cours, AuthorizeView n’affiche aucun contenu. Pour afficher le contenu lors de l’authentification, affectez le contenu au paramètre Authorizing :

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

Cette approche n’est normalement pas applicable aux applications Blazor côté serveur. Les applications Blazor côté serveur connaissent l’état de l’authentification dès que l’état est établi. Un contenu Authorizing peut être fourni dans le composant d’une application AuthorizeView, mais le contenu n’est jamais affiché.

Attribut [Authorize]

L’[Authorize]attribut est disponible dans les composantsRazor :

@page "/"
@attribute [Authorize]

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

Important

Utilisez uniquement [Authorize] sur des composants @page auxquels l’accès se fait via le routeur Blazor. L’autorisation est effectuée uniquement en tant qu’aspect du routage et pas pour les composants enfants rendus dans une page. Pour autoriser l’affichage d’éléments spécifiques dans une page, utilisez AuthorizeView à la place.

L’attribut [Authorize] prend aussi en charge l’autorisation basée sur les rôles ou sur une stratégie. Pour l’autorisation en fonction du rôle, utilisez le paramètre Roles :

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

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

Pour l’autorisation en fonction des stratégies, utilisez le paramètre Policy :

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

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

Si ni Roles ni Policy n’est spécifié, [Authorize] utilise la stratégie par défaut :

  • Les utilisateurs authentifiés (connectés) sont autorisés.
  • Les utilisateurs non authentifiés (déconnectés) ne sont pas autorisés.

Lorsque l’utilisateur n’est pas autorisé et si l’application ne personnalise pas le contenu non autorisé avec le composant Router, l’infrastructure affiche automatiquement le message de secours suivant :

Not authorized.

Autorisation des ressources

Pour autoriser des utilisateurs pour les ressources, transmettez les données de route de la requête au paramètre Resource de AuthorizeRouteView.

Dans le contenu Router.Found d’une route demandée :

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

Pour plus d’informations sur la façon dont les données d’état d’autorisation sont transmises et utilisées dans la logique procédurale, consultez la section Exposer l’état d’authentification sous la forme d’un paramètre en cascade.

Quand AuthorizeRouteView reçoit les données de route pour la ressource, les stratégies d’autorisation ont accès à RouteData.PageType et RouteData.RouteValues, ce qui permet à la logique personnalisée de prendre des décisions d’autorisation.

Dans l’exemple suivant, une stratégie EditUser est créée dans AuthorizationOptions pour la configuration du service d’autorisation de l’application (AddAuthorizationCore) avec la logique suivante :

  • Déterminer s’il existe une valeur de route avec la clé id. Si la clé existe, la valeur de route est stockée dans value.
  • Dans une variable nommée id, stocker value sous forme de chaîne ou définir une valeur de chaîne vide (string.Empty).
  • Si id n’est pas une chaîne vide, déclarer que la stratégie est satisfaite (retourner true) si la valeur de la chaîne commence par EMP. Sinon, déclarer que la stratégie échoue (retourner false).

Dans le fichier Program :

  • Ajouter des espaces de noms pour Microsoft.AspNetCore.Components et System.Linq :

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • Ajouter la stratégie :

    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’exemple précédent est une stratégie d’autorisation simplifiée à l’excès, simplement destinée à illustrer le concept à partir d’un exemple pratique. Pour plus d’informations sur la création et la configuration de stratégies d’autorisation, consultez Autorisation basée sur une stratégie dans ASP.NET Core.

Dans le composant EditUser suivant, la ressource au niveau de /users/{id}/edit possède un paramètre de route pour l’identificateur de l’utilisateur ({id}). Le composant utilise la stratégie d’autorisation EditUser précédente pour déterminer si la valeur de route de id commence par EMP. Si id commence par EMP, la stratégie aboutit et l’accès au composant est autorisé. Si id commence par une autre valeur que EMP ou si id est une chaîne vide, la stratégie échoue et le composant ne se charge pas.

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

Personnaliser le contenu non autorisé avec le composant Router

Le composant Router, conjointement avec le composant AuthorizeRouteView, permet à l’application de spécifier du contenu personnalisé si :

  • L’utilisateur ne répond pas à une condition [Authorize] appliquée au composant. Le balisage de l’élément <NotAuthorized> est affiché. L’attribut [Authorize] est décrit dans la section Attribut [Authorize].
  • L’autorisation asynchrone est en cours, ce qui signifie généralement que le processus d’authentification de l’utilisateur est en cours. Le balisage de l’élément <Authorizing> est affiché.

Important

Les fonctionnalités de routeur Blazor qui affichent du contenu <NotAuthorized> et <NotFound> ne sont pas opérationnelles pendant le rendu côté serveur statique (SSR statique), car le traitement des requêtes est entièrement géré par le traitement des requêtes du pipeline intergiciel ASP.NET Core et les composants Razor ne sont pas du tout rendus pour les requêtes non autorisées ou incorrectes. Utilisez des techniques côté serveur pour traiter les requêtes non autorisées et incorrectes pendant le rendu côté serveur statique. Pour plus d’informations, consultez Modes de rendu ASP.NET Core Blazor.

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

Le contenu de Authorized et de NotAuthorized peut inclure des éléments arbitraires, comme d’autres composants interactifs.

Remarque

L’élément précédent nécessite l’inscription des services d’état d’authentification en cascade dans le fichier Program de l’application :

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

Le contenu de NotFound, Authorized et NotAuthorized peut inclure des éléments arbitraires, comme d’autres composants interactifs.

Si le contenu NotAuthorized n’est pas spécifiée, le AuthorizeRouteView utilise le message de remplacement suivant :

Not authorized.

Une application créée à partir du modèle de projet Blazor WebAssembly dont l’authentification est activée comprend un composant RedirectToLogin qui est positionné dans le contenu <NotAuthorized> du composant Router. Lorsqu’un utilisateur n’est pas authentifié (context.User.Identity?.IsAuthenticated != true), le composant RedirectToLogin redirige le navigateur vers le point de terminaison authentication/login pour l’authentification. L’utilisateur est renvoyé à l’URL demandée après s’être authentifié auprès du fournisseur d’identity.

Logique procédurale

Si l’application est appelée à vérifier les règles d’autorisation dans le cadre de la logique procédurale, utilisez un paramètre en cascade de type Task<AuthenticationState> pour obtenir le ClaimsPrincipal de l’utilisateur. Task<AuthenticationState> peut être combiné avec d’autres services, comme IAuthorizationService, pour évaluer les stratégies.

Dans l’exemple suivant :

  • Le user.Identity.IsAuthenticated exécute le code pour les utilisateurs authentifiés (connectés).
  • Le user.IsInRole("admin") exécute le code pour les utilisateurs dans le rôle « Admin ».
  • Le (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded exécute le code pour les utilisateurs respectant la stratégie « éditeur de contenu ».

Une application Blazor côté serveur inclut les espaces de noms appropriés lorsqu’elle est créée à partir du modèle de projet. Dans une application Blazor côté client, confirmez la présence des espaces de noms Microsoft.AspNetCore.Authorization et Microsoft.AspNetCore.Components.Authorization dans le composant ou dans le fichier de l’application _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)
                {
                    // ...
                }
            }
        }
    }
}

Résoudre les erreurs

Erreurs courantes :

  • L’autorisation exige un paramètre en cascade de type Task<AuthenticationState>. Envisagez d’utiliser CascadingAuthenticationState pour le fournir.

  • La valeur null est reçue pour authenticationStateTask

Il est probable que le projet n’a pas été créé à l’aide d’un modèle Blazor côté serveur dont l’authentification est activée.

Dans .NET 7 ou versions antérieures, enveloppez un <CascadingAuthenticationState> dans certaines parties de l’arborescence de l’interface utilisateur, par exemple dans le routeur Blazor :

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

Dans .NET 8 ou versions ultérieures, n’utilisez pas le composant CascadingAuthenticationState :

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

Ajoutez à la place des services d’état d’authentification en cascade à la collection de services dans le fichier Program :

builder.Services.AddCascadingAuthenticationState();

Le composant CascadingAuthenticationState (.NET 7 ou versions antérieures) ou les services fournis par AddCascadingAuthenticationState (.NET 8 ou versions ultérieures) fournissent le paramètre en cascade Task<AuthenticationState> qui reçoit à son tour du service d’injection de dépendances AuthenticationStateProvider sous-jacent.

Informations d’identification personnelle (PII)

Microsoft utilise la définition RGPD pour les « données personnelles » (RGPD 4.1) lorsque la documentation traite des informations d’identification personnelle (PII).

L’IIP fait référence à toutes les informations relatives à une personne physique identifiée ou identifiable. Une personne physique identifiable est une personne qui peut être identifiée, directement ou indirectement, avec l’un des éléments suivants :

  • Nom
  • Numéro d’identification
  • Coordonnées d’emplacement
  • Identificateur en ligne
  • Autres facteurs spécifiques
    • Physique
    • Physiologiques
    • Génétique
    • Mental (psychologique)
    • Économique
    • Culturel
    • identity sociale

Ressources supplémentaires