Sécuriser une application ASP.NET Core Blazor WebAssembly hébergée avec l’ID Microsoft Entra
Cet article explique comment créer une solutionBlazor WebAssembly hébergée qui utilise Microsoft Entra ID (ME-ID) pour l’authentification. Cet article se concentre sur une application à locataire unique avec une inscription d’application Azure à locataire unique.
Cet article ne couvre pas l’inscription ME-ID multilocataire. Pour plus d’informations, consultez Rendre votre application multilocataire.
Cet article se concentre sur l’utilisation d’un locataire Microsoft Entra, comme décrit dans Démarrage rapide : Configurer un locataire. Si l’application est inscrite dans un locataire Azure Active Directory B2C, comme décrit dans Tutoriel : Créer un locataire Azure Active Directory B2C, mais suit les instructions de cet article, l’URI de l’ID d’application est géré différemment par ME-ID. Pour plus d’informations, consultez la section Utilisation d’un locataire Azure Active Directory B2C de cet article.
Pour obtenir une couverture supplémentaire du scénario de sécurité après avoir lu cet article, consultez ASP.NET Core Blazor WebAssembly scénarios de sécurité supplémentaires.
Procédure pas à pas
Les sous-sections de la procédure pas à pas expliquent comment :
- Créer un locataire dans Azure
- Inscrire une application API serveur auprès d’Azure
- Inscrire une application cliente auprès d’Azure
- Créer l’application Blazor
- Modifier la configuration Server
appsettings.json
- Modifier le schéma d’étendue du jeton d’accès par défaut
- Exécuter l’application
Créer un locataire dans Azure
Suivez les conseils d’aide fournis dans Démarrage rapide : Configurer un locataire pour créer un locataire dans ME-ID.
Inscrire une application API serveur auprès d’Azure
Inscrivez une application ME-ID pour l’application API serveur :
- Accédez à Microsoft Entra ID dans le portail Azure. Sélectionnez Applications>Inscriptions d’applications dans la barre latérale. Sélectionnez le bouton Nouvelle inscription.
- Fournissez un Nom pour l’application (par exemple, Blazor Server ME-ID).
- Choisissez un types de comptes pris en charge. Vous pouvez sélectionner Comptes dans cet annuaire organisationnel uniquement (locataire unique) pour cette expérience.
- L’application API Server ne nécessite pas d’URI de redirection dans ce scénario. Laissez la liste déroulante Sélectionner une plateforme non sélectionnée et n’entrez pas d’URI de redirection.
- Cet article suppose que l’application est inscrite dans un locataire Microsoft Entra. Si l’application est inscrite dans un locataire Azure Active Directory B2C, la case Autorisations>Accorder le consentement administrateur pour openid et offline_access autorisations est présente et activée. Désélectionnez la case à cocher pour désactiver le paramètre. Lorsque vous utilisez un client Active Directory, la case à cocher n’est pas présente.
- Sélectionnez Inscrire.
Enregistrez les informations suivantes :
- Application API serveur ID d’application (client) (par exemple
00001111-aaaa-2222-bbbb-3333cccc4444
) - ID de répertoire (locataire) (par exemple,
aaaabbbb-0000-cccc-1111-dddd2222eeee
) - Domaine principal/d’éditeur/de locataire ME-ID (par exemple
contoso.onmicrosoft.com
) : le domaine est disponible en tant que domaine d’éditeur dans le panneau Personnalisation du portail Azure de l’application inscrite.
Dans Autorisations d’API, supprimez l’autorisation User.Read>de Microsoft Graph, car l’application API serveur ne nécessite pas d’accès API supplémentaire pour simplement connecter des utilisateurs et appeler des points de terminaison d’API de serveur.
Dans Exposer une API :
- Confirmez ou ajoutez l’URI d’ID d’application au format
api://{SERVER API APP CLIENT ID}
. - Sélectionnez Ajouter une étendue.
- Sélectionnez Enregistrer et continuer.
- Indiquez un Nom d’étendue (par exemple
API.Access
). - Indiquez un Nom d’affichage du consentement administrateur (par exemple
Access API
). - Indiquez une Description du consentement administrateur (par exemple
Allows the app to access server app API endpoints.
). - Vérifiez que l’État a la valeur Activé.
- Sélectionnez Ajouter une étendue.
Enregistrez les informations suivantes :
- GUID d’URI d’ID d’application (par exemple, enregistrer des
00001111-aaaa-2222-bbbb-3333cccc4444
à partir de l’URI d’ID d’application deapi://00001111-aaaa-2222-bbbb-3333cccc4444
) - Nom de l’étendue (par exemple
API.Access
)
Important
Si une valeur personnalisée est utilisée pour l’URI d’ID d’application, les modifications de configuration sont requises pour les applications Server et Client une fois les applications créées à partir du modèle de projet Blazor WebAssembly. Pour plus d’informations, consultez la section Utiliser un URI d’ID d’application personnalisé.
Inscrire une application cliente auprès d’Azure
Inscrivez une application ME-ID pour l’application cliente :
- Accédez à Microsoft Entra ID dans le portail Azure. Sélectionnez Inscriptions d’applications dans la barre latérale. Sélectionnez le bouton Nouvelle inscription.
- Fournissez un nom pour l’application (par exemple, Blazor Client ME-ID).
- Choisissez un types de comptes pris en charge. Vous pouvez sélectionner Comptes dans cet annuaire organisationnel uniquement (locataire unique) pour cette expérience.
- Définissez la liste déroulante URI de redirection sur Application monopage (SPA) et fournissez l’URI de redirection suivante :
https://localhost/authentication/login-callback
. Si vous connaissez l’URI de redirection de production de l’hôte par défaut Azure (par exempleazurewebsites.net
) ou de l’hôte de domaine personnalisé (par exemplecontoso.com
), vous pouvez également ajouter l’URI de redirection de production en même temps que vous en fournissant l’URI de redirectionlocalhost
. Veillez à inclure le numéro de port des autres ports que le port:443
dans les URI de redirection de production que vous ajoutez. - Cet article suppose que l’application est inscrite dans un locataire Microsoft Entra. Si l’application est inscrite dans un locataire Azure Active Directory B2C, la case Autorisations>Accorder le consentement administrateur pour openid et offline_access autorisations est présente et activée. Désélectionnez la case à cocher pour désactiver le paramètre. Lorsque vous utilisez un client Active Directory, la case à cocher n’est pas présente.
- Sélectionnez Inscription.
Remarque
Il n’est pas nécessaire de fournir le numéro de port d’un URI de redirection localhost
ME-ID. Pour plus d’informations, consultez Restrictions et limitations de l’URI de redirection (URL de réponse) : exceptions localhost (documentation Entra).
Enregistrez l’ID d’application (client) de l’application Client (par exemple, 11112222-bbbb-3333-cccc-4444dddd5555
).
Dans Authentification>Configurations de la plateforme>Application monopage :
- Vérifiez que l’URI de redirection
https://localhost/authentication/login-callback
est présent. - Dans la section Octroi implicite, vérifiez que les cases des jetons d’accès et des jetons d’ID ne sont pas cochées. L’octroi implicite n’est pas recommandé pour les applications Blazor qui utilisent MSAL v2.0 ou version ultérieure. Pour plus d’informations, consultez Sécuriser ASP.NET Core Blazor WebAssembly.
- Les autres valeurs par défaut de l’application sont acceptables dans le cadre de cette expérience.
- Cliquez sur le bouton Enregistrer si vous avez apporté des modifications.
Dans autorisations d’API :
- Vérifiez que l’application dispose de l’autorisation User.Read>Microsoft Graph.
- Sélectionnez Ajouter une autorisation, puis Mes API.
- Sélectionnez l’application API serveur dans la colonne Nom (par exemple, Blazor Server ME-ID). Vous devez être propriétaire de l’inscription de l’application (et de l’inscription de l’application API s’il s’agit d’une application distincte) pour voir l’API dans la zone Mes API du Portail Azure. Pour plus d’informations, consultez Affecter le propriétaire de l’application (documentation Microsoft Entra).
- Ouvrez la liste des API.
- Activez l’accès à l’API (par exemple,
API.Access
). - Sélectionnez Ajouter des autorisations.
- Sélectionnez le bouton Octroyer un consentement administrateur pour {NOM DU LOCATAIRE}. Sélectionnez Oui pour confirmer.
Important
Si vous n’avez pas le droit d’octroyer le consentement administrateur au locataire à la dernière étape de la configuration des autorisations d’API, car le consentement à l’utilisation de l’application est délégué aux utilisateurs, vous devez suivre les étapes supplémentaires ci-après :
- L’application doit utiliser un domaine d’éditeur approuvé.
- Dans la configuration de l’application
Server
au sein du portail Azure, sélectionnez Exposer une API. Sous Applications clientes autorisées, sélectionnez le bouton pour Ajouter une application cliente. Ajoutez l’ID d’application (client) de l’applicationClient
(par exemple,11112222-bbbb-3333-cccc-4444dddd5555
).
Créer l’application Blazor
Dans un dossier vide, remplacez les espaces réservés dans la commande suivante par les informations enregistrées précédemment et exécutez la commande dans un interpréteur de commandes :
dotnet new blazorwasm -au SingleOrg --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI GUID}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{TENANT DOMAIN}" -ho -o {PROJECT NAME} --tenant-id "{TENANT ID}"
Avertissement
Évitez d’utiliser des tirets (-
) dans le nom d’application {PROJECT NAME}
, car ils empêchent la formation de l’identificateur d’application OIDC. La logique dans le modèle de projet Blazor WebAssembly utilise le nom du projet pour un identificateur d’application OIDC dans la configuration de la solution. La casse (BlazorSample
) ou les traits de soulignement (Blazor_Sample
) sont des alternatives acceptables. Pour plus d’informations, consultez Les tirets dans le nom d’un projet Blazor WebAssembly hébergé entravent la sécurité OIDC (dotnet/aspnetcore #35337).
Espace réservé | Nom du portail Azure | Exemple |
---|---|---|
{PROJECT NAME} |
— | BlazorSample |
{CLIENT APP CLIENT ID} |
ID d’application (client) pour l’application Client | 11112222-bbbb-3333-cccc-4444dddd5555 |
{DEFAULT SCOPE} |
Nom de l’étendue | API.Access |
{SERVER API APP CLIENT ID} |
ID d’application (client) pour l’application API Serveur | 00001111-aaaa-2222-bbbb-3333cccc4444 |
{SERVER API APP ID URI GUID} |
GUID d’URI d’ID d’application | 00001111-aaaa-2222-bbbb-3333cccc4444 (GUID uniquement, correspond au {SERVER API APP CLIENT ID} ) |
{TENANT DOMAIN} |
Domaine principal/d’éditeur/de locataire | contoso.onmicrosoft.com |
{TENANT ID} |
ID de l’annuaire (locataire) | aaaabbbb-0000-cccc-1111-dddd2222eeee |
L’emplacement de sortie spécifié avec l’option -o|--output
crée un dossier de projet s’il n’existe pas, et devient partie intégrante du nom du projet. Évitez d’utiliser des tirets (-
) dans le nom d’application, car cela empêche la formation de l’identificateur d’application OIDC (consultez l’AVERTISSEMENT précédent).
Important
Si une valeur personnalisée est utilisée pour l’URI d’ID d’application, les modifications de configuration sont requises pour les applications Server et Client une fois les applications créées à partir du modèle de projet Blazor WebAssembly. Pour plus d’informations, consultez la section Utiliser un URI d’ID d’application personnalisé.
Exécuter l’application
Exécutez l’application à partir du projet Server
. Quand vous utilisez Visual Studio, vous pouvez :
Sélectionnez la flèche déroulante vers le bas en regard du bouton Exécuter. Ouvrez Configurer des projets de démarrage dans la liste déroulante. Sélectionnez l’option Projet de démarrage unique. Confirmez ou remplacez le projet de démarrage par le projet
Server
.Vérifiez que le projet
Server
est mis en surbrillance dans l’Explorateur de solutions avant de démarrer l’application avec l’une des approches suivantes :- Sélectionnez le bouton Run.
- Utilisez Déboguer>Démarrer le débogage dans le menu.
- Appuyez sur F5.
Dans un interpréteur de commandes, accédez au dossier de projet
Server
de la solution. Exécutez la commandedotnet watch
(oudotnet run
).
Configurer User.Identity.Name
Les conseils d’aide fournis dans cette section couvrent le remplissage éventuel de User.Identity.Name
avec la valeur de la revendication name
.
L’API de l’application Server remplit User.Identity.Name
avec la valeur du type de revendication http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
(par exemple bbbb0000-cccc-1111-dddd-2222eeee3333@contoso.onmicrosoft.com
).
Pour configurer l’application afin de recevoir la valeur du type de revendication name
:
Ajoutez un espace de noms à Microsoft.AspNetCore.Authentication.JwtBearer dans le fichier
Program
:using Microsoft.AspNetCore.Authentication.JwtBearer;
Configurez le TokenValidationParameters.NameClaimType du JwtBearerOptions.
builder.Services.Configure<JwtBearerOptions>( JwtBearerDefaults.AuthenticationScheme, options => { options.TokenValidationParameters.NameClaimType = "name"; });
Parties de la solution
Cette section décrit les parties d’une solution générée à partir du modèle de projet Blazor WebAssembly ainsi que la façon dont les projets Client et Server de la solution sont configurés à titre de référence. Il n’existe aucun conseil d’aide spécifique à suivre dans cette section pour une application de base, si vous avez créé l’application en suivant les conseils d’aide de la section Procédure pas à pas. Les conseils d’aide de cette section sont utiles pour mettre à jour une application afin d’authentifier et d’autoriser les utilisateurs. Toutefois, il existe une autre approche pour la mise à jour d’une application. Elle consiste à créer une application à partir des conseils d’aide de la section Procédure pas à pas, et à déplacer les composants, les classes et les ressources de l’application à mettre à jour vers la nouvelle application.
Configuration appsettings.json
Cette section concerne l’application Server de la solution.
Le fichier appsettings.json
contient les options permettant de configurer le gestionnaire de porteur JWT utilisé pour valider les jetons d’accès. Ajoutez la section de configuration AzureAd
suivante :
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "{TENANT DOMAIN}",
"TenantId": "{TENANT ID}",
"ClientId": "{SERVER API APP CLIENT ID}",
"CallbackPath": "/signin-oidc",
"Scopes": "{SCOPES}"
}
}
Exemple :
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "contoso.onmicrosoft.com",
"TenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"ClientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"CallbackPath": "/signin-oidc",
"Scopes": "API.Access"
}
}
Important
Si l’application Server est inscrite pour utiliser un URI d’ID d’application personnalisé dans ME-ID (et non dans le format par défaut api://{SERVER API APP CLIENT ID}
), consultez la section Utilisation d’un URI d’ID d’application personnalisé. Les modifications sont requises dans les applications Server et Client.
Package d’authentification
Cette section concerne l’application Server de la solution.
La prise en charge de l’authentification et de l’autorisation des appels à ASP.NET API web Core avec la plateforme Microsoft identity est fournie par le Microsoft.Identity.Web
package.
Remarque
Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.
L’application Server d’une solution Blazor hébergée créée à partir du modèle Blazor WebAssembly comprend le package Microsoft.Identity.Web.UI
. Le package ajoute une IU pour l’authentification utilisateur dans les applications web. Il n’est pas utilisé par le framework Blazor. Si l’application Server n’est pas utilisée pour authentifier directement les utilisateurs, vous pouvez supprimer sans risque la référence de package du fichier projet de l’application Server.
Prise en charge du service d’authentification
Cette section concerne l’application Server de la solution.
La méthode AddAuthentication
configure les services d’authentification dans l’application ainsi que le gestionnaire de porteur JWT en tant que méthode d’authentification par défaut. La AddMicrosoftIdentityWebApi méthode configure les services pour protéger l’API web avec la plateforme Microsoft identity v2.0. Cette méthode attend une section AzureAd
dans la configuration de l’application avec les paramètres nécessaires pour initialiser les options d’authentification.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
Remarque
Quand un seul schéma d’authentification est inscrit, il est automatiquement utilisé en tant que schéma par défaut de l’application. Il n’est pas nécessaire d’indiquer le schéma pour AddAuthentication ou via AuthenticationOptions. Pour plus d’informations, consultez Vue d’ensemble de l’authentification ASP.NET Core ainsi que l’Annonce ASP.NET Core (aspnet/Announcements #490).
UseAuthentication et UseAuthorization permettent de vérifier que :
- L’application tente d’analyser et de valider les jetons dans les requêtes entrantes.
- Toute demande d’accès à une ressource protégée sans informations d’identification appropriées échoue.
app.UseAuthentication();
app.UseAuthorization();
Contrôleur WeatherForecast
Cette section concerne l’application Server de la solution.
Le contrôleur WeatherForecast
(Controllers/WeatherForecastController.cs
) expose une API protégée avec l’attribut [Authorize]
appliqué au contrôleur. Il est important de comprendre que :
- L’attribut
[Authorize]
de ce contrôleur d’API est la seule chose qui protège cette API contre les accès non autorisés. - L’attribut
[Authorize]
utilisé dans l’application Blazor WebAssembly indique uniquement à celle-ci que l’utilisateur doit être autorisé pour qu’elle fonctionne correctement.
[Authorize]
[ApiController]
[Route("[controller]")]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
...
}
}
Configuration wwwroot/appsettings.json
Cette section concerne l’application Client de la solution.
La configuration est fournie par le fichier wwwroot/appsettings.json
:
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/{TENANT ID}",
"ClientId": "{CLIENT APP CLIENT ID}",
"ValidateAuthority": true
}
}
Exemple :
{
"AzureAd": {
"Authority": "https://login.microsoftonline.com/e86c78e2-...-918e0565a45e",
"ClientId": "11112222-bbbb-3333-cccc-4444dddd5555",
"ValidateAuthority": true
}
}
Package d’authentification
Cette section concerne l’application Client de la solution.
Lorsqu’une application est créée pour utiliser des comptes professionnels ou scolaires (SingleOrg
), l’application reçoit automatiquement une référence de package pour la bibliothèque d’authentification Microsoft (Microsoft.Authentication.WebAssembly.Msal
). Le package fournit un ensemble de primitives qui permettent à l’application d’authentifier les utilisateurs et d’obtenir des jetons pour appeler les API protégées.
Si vous ajoutez l’authentification à une application, ajoutez manuellement le package Microsoft.Authentication.WebAssembly.Msal
à l’application.
Remarque
Pour obtenir des conseils sur l’ajout de packages à des applications .NET, consultez les articles figurant sous Installer et gérer des packages dans Flux de travail de la consommation des packages (documentation NuGet). Vérifiez les versions du package sur NuGet.org.
Le package Microsoft.Authentication.WebAssembly.Msal
ajoute de façon transitive le package Microsoft.AspNetCore.Components.WebAssembly.Authentication
à l’application.
Prise en charge du service d’authentification
Cette section concerne l’application Client de la solution.
La prise en charge des instances HttpClient qui incluent des jetons d’accès lors de l’envoi de demandes à l’application Server est ajoutée.
Dans le fichier Program
:
builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("{PROJECT NAME}.ServerAPI"));
L’espace réservé {PROJECT NAME}
représente le nom du projet au moment de la création de la solution. Par exemple, la spécification d’un nom de projet BlazorSample
produit un HttpClient nommé BlazorSample.ServerAPI
.
La prise en charge de l’authentification des utilisateurs est inscrite auprès du conteneur de services avec la méthode d’extension AddMsalAuthentication fournie par le package Microsoft.Authentication.WebAssembly.Msal
. Cette méthode configure les services nécessaires à l’application pour interagir avec le fournisseur d’identité (Identity Provider).
Dans le fichier Program
:
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});
La méthode AddMsalAuthentication accepte un rappel pour configurer les paramètres nécessaires à l’authentification d’une application. Les valeurs nécessaires à la configuration de l’application peuvent être obtenues à partir de la configuration ME-ID du portail Azure au moment où vous inscrivez l’application.
Étendues de jeton d’accès
Cette section concerne l’application Client de la solution.
Les étendues de jeton d’accès par défaut représentent la liste des étendues de jeton d’accès qui sont :
- Incluses par défaut dans la demande de connexion.
- Utilisées pour provisionner un jeton d’accès immédiatement après l’authentification.
Des étendues supplémentaires peuvent être ajoutées en fonction des besoins dans le fichier Program
:
builder.Services.AddMsalAuthentication(options =>
{
...
options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});
Spécifiez des étendues supplémentaires avec AdditionalScopesToConsent
:
options.ProviderOptions.AdditionalScopesToConsent.Add("{ADDITIONAL SCOPE URI}");
Remarque
AdditionalScopesToConsent ne peut pas provisionner les autorisations des utilisateurs délégués pour Microsoft Graph par l’interface utilisateur de consentement de Microsoft Entra ID quand un utilisateur utilise d’abord une application inscrite dans Microsoft Azure. Pour plus d’informations, consultez Utiliser l’API Graph avec Blazor WebAssembly ASP.NET Core.
Exemple d’étendue de jeton d’accès par défaut :
options.ProviderOptions.DefaultAccessTokenScopes.Add(
"api://00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
Pour plus d’informations, consultez les sections suivantes de l’article Scénarios supplémentaires :
Mode de connexion
Cette section concerne l’application Client de la solution.
Le framework utilise par défaut le mode de connexion par fenêtre indépendante, et revient au mode de connexion par redirection si une fenêtre indépendante ne peut pas être ouverte. Configurez MSAL pour utiliser le mode de connexion par redirection en affectant la valeur redirect
à la propriété LoginMode
de MsalProviderOptions :
builder.Services.AddMsalAuthentication(options =>
{
...
options.ProviderOptions.LoginMode = "redirect";
});
Le paramètre par défaut est popup
, et la valeur de chaîne ne respecte pas la casse.
Fichier Imports
Cette section concerne l’application Client de la solution.
L’espace de noms Microsoft.AspNetCore.Components.Authorization est rendu disponible dans l’ensemble de l’application via le fichier _Imports.razor
:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared
Page d'index
Cette section concerne l’application Client de la solution.
La page d’index (wwwroot/index.html
) comprend un script qui définit AuthenticationService
en JavaScript. AuthenticationService
gère les détails de bas niveau du protocole OIDC. L’application appelle de manière interne les méthodes définies dans le script pour effectuer les opérations d’authentification.
<script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>
Composant d’application
Cette section concerne l’application Client de la solution.
Le composant App
(App.razor
) est similaire au composant App
présent dans les applications Blazor Server :
- Le composant CascadingAuthenticationState gère l’exposition de AuthenticationState au rest de l’application.
- Le composant AuthorizeRouteView vérifie que l’utilisateur actuel est autorisé à accéder à une page donnée, ou affiche le composant
RedirectToLogin
. - Le composant
RedirectToLogin
gère la redirection des utilisateurs non autorisés vers la page de connexion.
En raison des changements apportés au framework dans les différentes versions d’ASP.NET Core, la syntaxe Razor du composant App
(App.razor
) n’est pas affichée dans cette section. Pour inspecter la syntaxe du composant d’une version donnée, utilisez l’une des approches suivantes :
Créez une application provisionnée pour l’authentification à partir du modèle de projet Blazor WebAssembly par défaut correspondant à la version d’ASP.NET Core que vous prévoyez d’utiliser. Inspectez le composant
App
(App.razor
) dans l’application générée.Inspectez le composant
App
(App.razor
) dans source de référence. Sélectionnez la version dans le sélecteur de branche, puis recherchez le composant dans le dossierProjectTemplates
du référentiel, car l’emplacement du composantApp
a changé au fil des années.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).
Composant RedirectToLogin
Cette section concerne l’application Client de la solution.
Le composant RedirectToLogin
(RedirectToLogin.razor
) :
- Gère la redirection des utilisateurs non autorisés vers la page de connexion.
- L’URL actuelle à laquelle l’utilisateur tente d’accéder est conservée pour permettre à l’utilisateur de retourner à cette page en cas d’authentification réussie avec :
- État de l’historique de navigation dans ASP.NET Core dans .NET 7 ou une version ultérieure.
- Chaîne de requête dans ASP.NET Core dans .NET 6 ou une version antérieure.
Inspectez le composant RedirectToLogin
dans source de référence. L’emplacement du composant ayant changé au fil du temps, servez-vous des outils de recherche GitHub pour le retrouver.
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).
Composant LoginDisplay
Cette section concerne l’application Client de la solution.
Le composant LoginDisplay
(LoginDisplay.razor
) est affiché dans le composant MainLayout
(MainLayout.razor
) et gère les comportements suivants :
- Pour les utilisateurs authentifiés :
- Affiche le nom d’utilisateur actuel.
- Propose un lien vers la page de profil utilisateur dans ASP.NET Core Identity.
- Propose un bouton pour se déconnecter de l’application.
- Pour les utilisateurs anonymes :
- Permet de s’inscrire.
- Permet de se connecter.
En raison des changements apportés au framework dans les différentes versions d’ASP.NET Core, la syntaxe Razor du composant LoginDisplay
n’est pas affichée dans cette section. Pour inspecter la syntaxe du composant d’une version donnée, utilisez l’une des approches suivantes :
Créez une application provisionnée pour l’authentification à partir du modèle de projet Blazor WebAssembly par défaut correspondant à la version d’ASP.NET Core que vous prévoyez d’utiliser. Inspectez le composant
LoginDisplay
dans l’application générée.Inspectez le composant
LoginDisplay
dans la source de référence. L’emplacement du composant ayant changé au fil du temps, servez-vous des outils de recherche GitHub pour le retrouver. Le contenu mis en modèle pourHosted
égal àtrue
est utilisé.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).
Composant Authentication
Cette section concerne l’application Client de la solution.
La page produite par le composant Authentication
(Pages/Authentication.razor
) définit les routes nécessaires à la gestion des différentes phases d’authentification.
Le composant RemoteAuthenticatorView :
- Est fourni par le package
Microsoft.AspNetCore.Components.WebAssembly.Authentication
. - Gère l’exécution des actions appropriées à chaque phase de l’authentification.
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action" />
@code {
[Parameter]
public string? Action { get; set; }
}
Remarque
Les types références null (NRT, nullable reference types) et l’analyse statique de l’état nul du compilateur .NET sont pris en charge dans ASP.NET Core dans .NET 6 ou une version ultérieure. Avant la publication d’ASP.NET Core dans .NET 6, le type string
apparaît sans la désignation de type nul (?
).
Composant FetchData
Cette section concerne l’application Client de la solution.
Le composant FetchData
montre comment :
- Provisionner un jeton d’accès.
- Utiliser le jeton d’accès pour appeler une API de ressource protégée dans l’application serveur.
La directive @attribute [Authorize]
indique au système d’autorisation Blazor WebAssembly que l’utilisateur doit être autorisé pour pouvoir visiter ce composant. La présence de l’attribut dans l’application Client
n’empêche pas l’appel de l’API sur le serveur sans les informations d’identification appropriées. L’application Server
doit également utiliser [Authorize]
sur les points de terminaison appropriés pour les protéger correctement.
IAccessTokenProvider.RequestAccessToken se charge de demander un jeton d’accès qui peut être ajouté à la demande d’appel de l’API. Si le jeton est mis en cache ou si le service peut provisionner un nouveau jeton d’accès sans interaction de l’utilisateur, la demande de jeton aboutit. Sinon, la demande de jeton échoue avec un AccessTokenNotAvailableException, qui est intercepté dans une instruction try-catch
.
Pour obtenir le jeton réel à inclure dans la demande, l’application doit vérifier la réussite de la demande en appelant tokenResult.TryGetToken(out var token)
.
Si la demande aboutit, la variable de jeton est renseignée avec le jeton d’accès. La propriété AccessToken.Value du jeton expose la chaîne littérale à inclure dans l’en-tête de demande Authorization
.
Si le jeton n’a pas pu être approvisionné sans interaction utilisateur et a entraîné un échec de requête :
- ASP.NET Core dans .NET 7 ou une version ultérieure : l’application accède à
AccessTokenResult.InteractiveRequestUrl
avec leAccessTokenResult.InteractionOptions
donné pour permettre l’actualisation du jeton d’accès. - ASP.NET Core dans .NET 6 ou une version antérieure : le résultat du jeton contient une URL de redirection. La navigation vers cette URL permet à l’utilisateur d’accéder à la page de connexion, puis de revenir à la page active après une authentification réussie.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http
...
@code {
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
try
{
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
Utilisation d’un locataire Azure Active Directory B2C
Si l’application est inscrite dans un locataire Azure Active Directory B2C, comme décrit dans Tutoriel : Créer un locataire Azure Active Directory B2C, mais suit les instructions de cet article, l’URI de l’ID d’application est géré différemment par ME-ID.
Vous pouvez vérifier le type de locataire d’un locataire existant en sélectionnant le lien Gérer les locataires en haut de l’organisation ME-ID Vue d’ensemble. Examinez le type de locataire valeur de colonne pour l’organisation. Cette section concerne les applications qui suivent les instructions de cet article, mais qui sont inscrites dans un locataire Azure Active Directory B2C.
Au lieu de l’URI d’ID d’application correspondant au format api://{SERVER API APP CLIENT ID OR CUSTOM VALUE}
, l’URI d’ID d’application a le format https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}
. Cette différence affecte les configurations des applications Client et Server :
Pour l’application API serveur, définissez la
Audience
dans le fichier de paramètres de l’application (appsettings.json
) pour qu’elle corresponde à l’audience de l’application (URI d’ID d’application) fournie par le portail Azure sans barre oblique de fin :"Audience": "https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}"
Exemple :
"Audience": "https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444"
Dans le fichier
Program
de l’applicationClient
, définissez l’audience de l’étendue (URI de l’ID d’application) pour qu’elle corresponde à l’audience de l’application API du serveur :options.ProviderOptions.DefaultAccessTokenScopes .Add("https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}/{DEFAULT SCOPE}");
Dans l’étendue précédente, l’URI/audience de l’ID d’application est la partie
https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}
de la valeur, qui n’inclut pas de barre oblique de fin (/
) et n’inclut pas le nom de l’étendue ({DEFAULT SCOPE}
).Exemple :
options.ProviderOptions.DefaultAccessTokenScopes .Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
Dans l’étendue précédente, l’URI/audience de l’ID d’application est la partie
https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444
de la valeur, qui n’inclut pas de barre oblique de fin (/
) et n’inclut pas le nom de l’étendue (API.Access
).
Utilisation d’un URI d’ID d’application personnalisé
Si l’URI d’ID d’application est une valeur personnalisée, vous devez mettre à jour manuellement l’URI d’étendue du jeton d’accès par défaut dans l’application Client et ajouter l’audience à la configuration ME-ID de l’application Server.
Important
La configuration suivante n’est pas requise lorsque l’URI d’ID d’application de api://{SERVER API APP CLIENT ID}
est utilisé.
Exemple d’URI d’ID d’application de urn://custom-app-id-uri
et nom d’étendue de API.Access
:
Dans le fichier
Program
de l’application Client :options.ProviderOptions.DefaultAccessTokenScopes.Add( "urn://custom-app-id-uri/API.Access");
Dans
appsettings.json
de l’application Server, ajoutez une entrée deAudience
avec uniquement l’URI d’ID d’application et aucune barre oblique de fin :"Audience": "urn://custom-app-id-uri"
Résoudre des problèmes
Logging
Pour activer la journalisation de débogage ou de trace pour l’authentification Blazor WebAssembly, consultez la section Journalisation d’authentification côté client de la Journalisation Blazor ASP.NET Core avec le sélecteur de version d’article défini sur ASP.NET Core 7.0 ou une version ultérieure.
Erreurs courantes
Mauvaise configuration de l’application ou du fournisseur d’identité (Identity Provider)
Les erreurs les plus courantes sont provoquées par une configuration incorrecte. Voici quelques exemples :
- Selon les besoins du scénario, une autorité, une instance, un ID de locataire, un domaine de locataire, un ID client ou un URI de redirection manquant ou incorrect empêche une application d’authentifier les clients.
- Les étendues de requêtes erronées empêchent les clients d’accéder aux points de terminaison d’API web du serveur.
- Des autorisations d’API serveur incorrectes ou manquantes empêchent les clients d’accéder aux points de terminaison d’API web du serveur.
- Exécution de l’application sur un autre port que celui configuré dans l’URI de redirection de l’inscription d’application de l’IP. Notez qu’un port n’est pas requis pour Microsoft Entra ID et pour une application s’exécutant à une adresse de test de développement
localhost
. Cependant, la configuration du port de l’application et le port où l’application s’exécute doivent correspondre pour les adresses non-localhost
.
Les sections de configuration présentes dans les conseils d’aide de cet article montrent des exemples de configuration appropriée. Examinez attentivement chaque section de l’article à la recherche d’une mauvaise configuration de l’application et du fournisseur d’identité.
Si la configuration semble correcte :
Analysez les journaux des applications.
Examinez le trafic réseau entre l’application cliente et le fournisseur d’identité ou l’application serveur à l’aide des outils de développement du navigateur. Bien souvent, un message d’erreur exact ou un message indiquant la cause du problème est retourné au client par le fournisseur d’identité ou l’application serveur, une fois qu’une demande a été effectuée. Vous trouverez des conseils d’aide sur les outils de développement dans les articles suivants :
- Google Chrome (documentation Google)
- Microsoft Edge
- Mozilla Firefox (documentation Mozilla)
Pour les versions de Blazor dans lesquelles un jeton JSON Web Token (JWT) est utilisé, décodez le contenu du jeton utilisé pour authentifier un client ou pour accéder à une API web de serveur, en fonction de l’emplacement du problème. Pour plus d’informations, consultez Inspecter le contenu d’un jeton JWT (JSON Web Token).
L’équipe de documentation peut répondre aux commentaires et bogues relatifs aux articles (ouvrez un problème à partir de la section de commentaires de cette page). Toutefois, elle ne peut pas fournir de support produit. Plusieurs forums de support publics sont disponibles pour vous aider à résoudre les problèmes liés à une application. Nous recommandons ce qui suit :
Les forums précédents ne sont pas détenus ou contrôlés par Microsoft.
Pour les rapports de bogues de framework reproductibles, non liés à la sécurité, non sensibles et non confidentiels, ouvrez un problème auprès de l’unité de produit ASP.NET Core. N’ouvrez pas de problème auprès de l’unité de produit tant que vous n’avez pas investigué de manière approfondie la cause du problème, sans pouvoir le résoudre par vous-même ou avec l’aide de la communauté sur un forum de support public. L’unité de produit ne peut pas résoudre les problèmes d’applications individuelles qui sont défaillantes en raison d’une mauvaise configuration ou de cas d’usage impliquant des services tiers. Si un rapport est de nature sensible ou confidentielle, ou s’il décrit une faille de sécurité potentielle dans le produit que des attaquants peuvent exploiter, consultez Signaler des problèmes de sécurité et des bugs (référentiel GitHub
dotnet/aspnetcore
).Client non autorisé pour ME-ID
Info : Échec de l’autorisation Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]. Ces conditions n’ont pas été remplies : DenyAnonymousAuthorizationRequirement : Nécessite un utilisateur authentifié.
Erreur de rappel de la connexion à partir de ME-ID :
- Erreur :
unauthorized_client
- Description :
AADB2C90058: The provided application is not configured to allow public clients.
Pour résoudre l’erreur :
- Dans le portail Azure, accédez au manifeste de l’application.
- Affectez à l’attribut
allowPublicClient
la valeurnull
outrue
.
- Erreur :
Cookies et données de site
Les cookies et les données de site peuvent persister au fil des mises à jour des applications, et interférer avec les tests et la résolution des problèmes. Effacez ce qui suit quand vous apportez des changements au code d’application, au compte d’utilisateur du fournisseur ou à la configuration de l’application :
- Cookies de connexion des utilisateurs
- Cookies d’applications
- Données de site mises en cache et stockées
Il existe une approche qui permet d’empêcher les cookies et les données de site persistants d’interférer avec les tests et la résolution des problèmes. Elle consiste à :
- Configurer un navigateur
- Utilisez un navigateur de test que vous pouvez configurer pour supprimer tous les cookies et toutes les données de site à chaque fois qu’il se ferme.
- Vérifiez que le navigateur est fermé manuellement ou par l’IDE chaque fois qu’un changement est apporté à la configuration de l’application, de l’utilisateur de test ou du fournisseur.
- Utilisez une commande personnalisée pour ouvrir un navigateur en mode InPrivate ou Incognito dans Visual Studio :
- Ouvrez la boîte de dialogue Parcourir avec à partir du bouton Exécuter de Visual Studio.
- Cliquez sur le bouton Ajouter.
- Indiquez le chemin de votre navigateur dans le champ Programme. Les chemins d’exécutables suivants sont des emplacements d’installation classiques de Windows 10. Si votre navigateur est installé à un autre emplacement, ou si vous n’utilisez pas Windows 10, indiquez le chemin de l’exécutable du navigateur.
- Microsoft Edge :
C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
- Google Chrome :
C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
- Mozilla Firefox :
C:\Program Files\Mozilla Firefox\firefox.exe
- Microsoft Edge :
- Dans le champ Arguments, indiquez l’option de ligne de commande utilisée par le navigateur pour qu’il s’ouvre en mode InPrivate ou Incognito. Certains navigateurs nécessitent l’URL de l’application.
- Microsoft Edge : Utilisez
-inprivate
. - Google Chrome : utilisez
--incognito --new-window {URL}
, où l’espace réservé{URL}
correspond à l’URL à ouvrir (par exemple,https://localhost:5001
). - Mozilla Firefox : utilisez
-private -url {URL}
, où l’espace réservé{URL}
correspond à l’URL à ouvrir (par exemplehttps://localhost:5001
).
- Microsoft Edge : Utilisez
- Indiquez un nom dans le champ Nom convivial. Par exemple,
Firefox Auth Testing
- Cliquez sur le bouton OK.
- Pour éviter d’avoir à sélectionner le profil de navigateur pour chaque itération de test avec une application, définissez le profil en tant que profil par défaut avec le bouton Par défaut.
- Vérifiez que le navigateur est fermé par l’IDE chaque fois qu’un changement est apporté à la configuration de l’application, de l’utilisateur de test ou du fournisseur.
Mises à niveau d’application
Une application fonctionnelle peut échouer immédiatement après la mise à niveau du kit SDK .NET Core sur l’ordinateur de développement ou la modification des versions de package au sein de l’application. Dans certains cas, les packages incohérents peuvent bloquer une application quand vous effectuez des mises à niveau majeures. Vous pouvez résoudre la plupart de ces problèmes en suivant les instructions suivantes :
- Effacez les caches de package NuGet du système local en exécutant
dotnet nuget locals all --clear
à partir d’un interpréteur de commandes. - Supprimez les dossiers
bin
etobj
du projet. - Restaurez et regénérez le projet.
- Supprimez tous les fichiers du dossier de déploiement sur le serveur avant de redéployer l’application.
Remarque
L’utilisation de versions de package incompatibles avec le framework cible de l’application n’est pas prise en charge. Pour plus d’informations sur un package, utilisez la Galerie NuGet ou l’Explorateur de packages FuGet.
Exécuter l’application Server
Quand vous testez et résolvez les problèmes liés à une solution Blazor WebAssembly hébergée, vérifiez que vous exécutez l’application à partir du projet Server
.
Inspecter l’utilisateur
Le composant User
suivant peut être utilisé directement dans les applications, ou servir de base à une personnalisation supplémentaire.
User.razor
:
@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService
<h1>@AuthenticatedUser?.Identity?.Name</h1>
<h2>Claims</h2>
@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
<p class="claim">@(claim.Type): @claim.Value</p>
}
<h2>Access token</h2>
<p id="access-token">@AccessToken?.Value</p>
<h2>Access token claims</h2>
@foreach (var claim in GetAccessTokenClaims())
{
<p>@(claim.Key): @claim.Value.ToString()</p>
}
@if (AccessToken != null)
{
<h2>Access token expires</h2>
<p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
<p id="access-token-expires">@AccessToken.Expires</p>
<h2>Access token granted scopes (as reported by the API)</h2>
@foreach (var scope in AccessToken.GrantedScopes)
{
<p>Scope: @scope</p>
}
}
@code {
[CascadingParameter]
private Task<AuthenticationState> AuthenticationState { get; set; }
public ClaimsPrincipal AuthenticatedUser { get; set; }
public AccessToken AccessToken { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
var state = await AuthenticationState;
var accessTokenResult = await AuthorizationService.RequestAccessToken();
if (!accessTokenResult.TryGetToken(out var token))
{
throw new InvalidOperationException(
"Failed to provision the access token.");
}
AccessToken = token;
AuthenticatedUser = state.User;
}
protected IDictionary<string, object> GetAccessTokenClaims()
{
if (AccessToken == null)
{
return new Dictionary<string, object>();
}
// header.payload.signature
var payload = AccessToken.Value.Split(".")[1];
var base64Payload = payload.Replace('-', '+').Replace('_', '/')
.PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');
return JsonSerializer.Deserialize<IDictionary<string, object>>(
Convert.FromBase64String(base64Payload));
}
}
Inspecter le contenu d’un jeton JWT (JSON Web Token)
Pour décoder un jeton JWT (JSON Web Token), utilisez l’outil jwt.ms de Microsoft. Les valeurs de l’IU ne quittent jamais votre navigateur.
Exemple de jeton JWT codé (raccourci pour des raisons d’affichage) :
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q
Exemple JWT décodé par l’outil pour une application qui s’authentifie auprès d’Azure AAD B2C :
{
"typ": "JWT",
"alg": "RS256",
"kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
"exp": 1610059429,
"nbf": 1610055829,
"ver": "1.0",
"iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
"sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
"nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
"iat": 1610055829,
"auth_time": 1610055822,
"idp": "idp.com",
"tfp": "B2C_1_signupsignin"
}.[Signature]
Ressources supplémentaires
- Configurer le domaine d’éditeur d’une application
- Manifeste de l’application Microsoft Entra ID : attribut identifierUris
- Autres scénarios de sécurité ASP.NET Core Blazor WebAssembly
- Créer une version personnalisée de la bibliothèque JavaScript Authentication.MSAL
- Requêtes d’API web non authentifiées ou non autorisées dans une application avec un client par défaut sécurisé
- ASP.NET Core Blazor WebAssembly avec des groupes et des rôles Microsoft Entra ID (.NET 5 à .NET 7)
- Plateforme d’identity Microsoft et Microsoft Entra ID avec ASP.NET Core
- Documentation de la plateforme d’identity Microsoft
- Démarrage rapide : inscrire une application à l’aide de la plateforme d’identity Microsoft
- Meilleures pratiques de sécurité pour les propriétés d’application dans Microsoft Entra ID