Partage via


Applications Blazor sécurisées côté serveur ASP.NET Core

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 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 prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 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 8 de cet article.

Cet article explique comment sécuriser les applications Blazor côté serveur en tant qu'applications ASP.NET Core.

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 n'est établi qu'au démarrage de l'application, c'est-à-dire lorsque l'application se connecte pour la première fois au WebSocket. 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 Scénarios de sécurité supplémentaires ASP.NET Core Blazor côté serveur.

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 Blazor circuit, que vous pouvez mettre à jour à tout moment sur le serveur à l’aide d’une revalidation AuthenticationStateProvider](#additional-authentication-state-providers).

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 utilisent les types de référence null (NRT, nullable reference types) et l'analyse statique de l'état null du compilateur .NET, qui sont pris en charge dans ASP.NET Core 6 et ses versions ultérieures. Lorsque vous ciblez ASP.NET Core 5.0 ou version antérieure, supprimez la désignation de type null (?) des exemples de cet article.

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 Identity de l’infrastructure Blazor, 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.

Pour plus d’informations sur l’interface utilisateur BlazorIdentity et des conseils sur l’intégration de connexions externes via des sites web sociaux, consultez Nouveautés de l’identity dans .NET 8.

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

Fournisseurs d’état d’authentification supplémentaires

Deux classes supplémentaires dérivées de l’aide sur la gestion de l’état d’authentification AuthenticationStateProvider sur le 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).

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

Ressources supplémentaires