Partager via


Authentification et autorisation avec ASP.NET Core Blazor

Note

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

Warning

Cette version d'ASP.NET Core n'est plus prise en charge. Pour plus d’informations, consultez la stratégie de prise en charge de .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’identité 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 le code d’autorisation s’exécutant 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, le code d’autorisation s’exécutant sur le client ne peut pas être considéré comme source de confiance pour appliquer 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 Pages Razor ne s’appliquent pas aux composants Razor routables. Si un composant non routable Razor 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 reste 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 des applications 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 création de composants Razor qui gèrent directement des tâches Identity est possible pour plusieurs scénarios, mais n’est pas recommandée ni 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, voir Générer automatiquement des modèles Scaffold ASP.NET Core Identity dans une application Blazor côté serveur.

Note

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 en .NET 6 ou une version ultérieure. Lorsque vous ciblez ASP.NET Core 5.0 ou une version antérieure, supprimez la désignation de type null (?) dans les exemples de cet article.

Conserver en toute sécurité les données sensibles et les informations d'identification

Ne stockez pas de secrets d'application, de chaînes de connexion, d'informations d'identification, de mots de passe, de numéros d'identification personnels (PIN), de code .NET/C# privé ou de clés/tokens privés dans le code côté client, qui est toujours non sécurisé. Le code Blazor côté 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/staging et de production, le code Blazor côté 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 local, nous recommandons d'éviter d'utiliser des variables d'environnement pour stocker des données sensibles, car les variables d'environnement ne constituent pas l'approche la plus sûre. Pour les tests de développement local, il est recommandé d'utiliser l'outil Secret Manager pour sécuriser les données sensibles. Pour plus d'informations, reportez-vous aux ressources suivantes :

Pour le développement et les tests locaux côté client et côté serveur, utilisez l’outil Secret Manager 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é d'authentification auprès des services Azure sans stocker d’informations d’identification dans le code de l’application. Pour plus d'informations, reportez-vous aux ressources suivantes :

Prise en charge de l'antifalsification

Le modèle Blazor :

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

Le service AntiforgeryStateProvider fournit un accès à un jeton antifalsification 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 antifalsification sont disponibles pour les composants interactifs, même s’ils n’ont pas accès à la requête.

Note

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

Pour plus d'informations, reportez-vous aux 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 connexion SignalR 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 les utilisateurs pour fournir des services personnalisés ou réagir aux mises à jour de l’utilisateur, consultez ASP.NET Core côté serveur et des scénarios de sécurité supplémentaires Blazor Web App.

Blazor diffère d’une application web traditionnelle rendue sur serveur 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’abstraction RevalidatingAuthenticationStateProvider.

Important

La mise en œuvre d'un NavigationManager personnalisé 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 AuthenticationStateProvider personnalisé.

Note

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 en .NET 6 ou une version ultérieure. Lorsque vous ciblez ASP.NET Core 5.0 ou une version antérieure, supprimez la désignation de type null (?) dans les exemples de cet article.

Le service AuthenticationStateProvider intégré ou personnalisé obtient les données d’état d’authentification via 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, voir Authentification et autorisation ASP.NET Core Blazor.

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

Warning

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 l'accès à une entrée donnée. En supposant que les utilisateurs ne contrôlent pas les clés de cache utilisées, 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, voir Gestion de l’état ASP.NET Core Blazor.

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

Dans les environnements de test/staging et de production, le code Blazor côté 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 local, nous recommandons d'éviter d'utiliser des variables d'environnement pour stocker des données sensibles, car les variables d'environnement ne constituent pas l'approche la plus sûre. Pour les tests de développement local, il est recommandé d'utiliser l'outil Secret Manager pour sécuriser les données sensibles. Pour plus d'informations, reportez-vous aux ressources suivantes :

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

Modèle de projet

Créez une nouvelle application Blazor côté serveur 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’identités Microsoft: pour plus d’informations, veuillez consulter la section ASP.NET Core Blazor authentification et autorisation.
  • Windows : utiliser l’authentification Windows.

Interface utilisateur Blazor Identity (Comptes individuels)

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

Le modèle Blazor Web App génère automatiquement 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, 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 du framework 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 la 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 d'é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, voir Gérer l’état d’authentification dans des Blazor Web Apps.

Uniquement pour les solutions Serveur interactif, IdentityRevalidatingAuthenticationStateProvider (source de référence) est 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é.

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 la 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 d'é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).

Blazor Identity dépend d'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 composants hors Identity tout en appliquant le SSR statique pour les composants Identity, voir Modes de rendu ASP.NET Core Blazor.

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

Note

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 des Blazor Web Apps

Cette section s’applique aux Blazor Web Apps 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 du 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 (rechargement complet 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 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 Blazor Web App et décrits ci-dessous.

Dans le fichier Program du projet serveur, appelez AddAuthenticationStateSerialization, qui sérialise l'AuthenticationState retourné par l'AuthenticationStateProvider côté serveur à l’aide du service d'é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 Program du projet client (.Client), 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 d'état de composant persistant (PersistentComponentState). Il doit y avoir un appel à AddAuthenticationStateSerialization correspondant dans le projet serveur.

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
  • PersistingRevalidatingAuthenticationStateProvider (source de référence) : pour les Blazor Web Apps 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. Celui-ci 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 Apps 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. Celui-ci 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 Apps 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. Cela n’inclut pas les jetons d'authentification 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.

Note

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 la génération automatique d'Identity dans une application Blazor, voir Générer automatiquement Identity dans des projets ASP.NET Core.

Générer automatiquement Identity dans une application Blazor côté serveur :

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, voir Utiliser Identity pour sécuriser un back-end d’API web pour des SPA.

Injectez AuthenticationStateProvider pour les services étendus à 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 d'AuthenticationStateProvider qui n’est pas correctement initialisée.

Pour accéder à AuthenticationStateProvider dans un service étendu à un composant, injectez dans AuthenticationStateProvider la directive @inject ou l’attribut [Inject] et transmettez-le au service en tant que paramètre. Cette approche garantit que l’instance correcte et initialisée de l'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 conformément à l'étendue. 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 ASP.NET Core Blazor.

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

Pour éviter d’afficher du contenu non autorisé, par exemple du contenu dans un composant AuthorizeView, 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.

    Note

    Le rendu d'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 Blazor Web App, le pré-rendu est habituellement désactivé lorsque 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, voir Modes de rendu ASP.NET Core Blazor.

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

    <component type="typeof(App)" render-mode="Server" />
    
  • Authentifiez 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, voir 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 utilisateur

En dépit du mot « state » dans le nom, AuthenticationStateProvider n’est pas destiné au stockage de l’état utilisateur général. 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 ASP.NET Core Identity que les applications Razor Pages 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, voir Gestion de l’état ASP.NET Core Blazor.

Abstractions de sécurité supplémentaires

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

Note

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 lorsqu'il se déconnecte d’un onglet, vous devez implémenter RevalidatingServerAuthenticationStateProvider (source de référence) avec un RevalidationInterval court.

Note

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

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 Blazor côté serveur. 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 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 contrôles d’authentification côté client peuvent être contournés, car tout le code côté client peut être modifié par les utilisateurs. Cela vaut également pour toutes les technologies d’application côté client, y compris les infrastructures d’application JavaScript SPA 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, voir Sécuriser ASP.NET Core Blazor WebAssembly.

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 ou 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é, voir État d’authentification ASP.NET Core Blazor, 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 renvoie les revendications de l’utilisateur (claims) pour affichage dans l’interface utilisateur.
  • La ligne qui obtient le ClaimsPrincipal.FindAll des appels du nom de l’utilisateur (surname) 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é dans les applications, voir État d'authentification ASP.NET Core Blazor.

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

Si les données d’état d’authentification sont nécessaires à la logique procédurale, par exemple au moment d’effectuer 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 illustré dans 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 un Task<AuthenticationState>paramètre en cascade en utilisant 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 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 le Task<AuthenticationState>paramètre en cascade avec les composants AuthorizeRouteView et CascadingAuthenticationState.

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

Note

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 les services d'options et d’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.

Composant AuthorizeView

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’identité 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 composant AuthorizeView 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 méthode HandleClick 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 Apps 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, voir Modes de rendu ASP.NET Core Blazor.

Warning

Le balisage côté client et les méthodes associées à AuthorizeView sont uniquement protégés contre l'affichage et l’exécution dans l’interface utilisateur rendue 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é vers une API de serveur et n’est jamais stocké dans l’application. Pour plus d’informations, voir Appeler une API web à partir d’une application ASP.NET Core Blazor et Scénarios de sécurité supplémentaires ASP.NET Core Blazor WebAssembly.

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 les composants AuthorizeView :

<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 le AuthorizeView externe avec l’approche standard pour accéder au contexte (@context.User). Le contexte est accessible dans le AuthorizeView interne avec le contexte innerContext nommé (@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 paramètre Policy 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 par défaut, 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égies (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 le framework. Par exemple, billing administrator est un format de nom de rôle ou 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 est 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 pas normalement 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. Le contenu Authorizing peut être fourni dans le composant AuthorizeView d’une application, mais le contenu n’est jamais affiché.

Attribut [Authorize]

L’attribut [Authorize] 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, le framework 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 pour 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 SSR statique. Pour plus d’informations, voir 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.

Note

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é, AuthorizeRouteView utilise le message de base 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 redirigé vers l’URL demandée après s’être authentifié auprès du fournisseur d’identité.

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 :

  • user.Identity.IsAuthenticated exécute le code pour les utilisateurs authentifiés (connectés).
  • user.IsInRole("admin") exécute le code pour les utilisateurs dans le rôle « Admin ».
  • (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 avec l’authentification activée.

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

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

En .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 des « données personnelles » du RGPD (RGPD 4.1) lorsque la documentation traite des informations d’identification personnelle (PII).

Les PII désignent toutes les informations concernant une personne physique identifiée ou naturellement identifiable. Une personne physique identifiable est une personne qui peut être identifiée, directement ou indirectement, avec l’un des éléments suivants :

  • Name
  • Numéro d’identification
  • Emplacement : coordonnées
  • Identificateur en ligne
  • Autres facteurs spécifiques
    • Physique
    • Physiologique
    • Génétique
    • Mental (psychologique)
    • Économique
    • Culturel
    • Identité sociale

Ressources supplémentaires