Share via


Groupes Microsoft Entra (ME-ID), rôles d’administrateur et rôles d’application

Remarque

Ceci n’est pas la dernière version de cet article. 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 configurer Blazor WebAssembly pour utiliser des groupes et des rôles Microsoft Entra ID.

Microsoft Entra (ME-ID) fournit plusieurs approches d’autorisation qui peuvent être combinées avec ASP.NET Core Identity:

  • Groupes
    • Sécurité
    • Microsoft 365
    • Distribution
  • Rôles
    • Rôles d’administrateur ME-ID
    • Rôles d'application

Les conseils de cet article s’appliquent aux scénarios de déploiement Blazor WebAssembly ME-ID décrits dans les rubriques suivantes :

Les conseils de l’article fournissent des instructions pour les applications clients et serveurs :

  • CLIENT : Applications Autonome Blazor WebAssembly.
  • SERVEUR : Applications API/API Web du serveur ASP.NET Core. Vous pouvez ignorer les conseils SERVEUR tout au long de l’article pour une application Blazor WebAssembly autonome.
  • CLIENT : applications autonomes Blazor WebAssembly ou l’application Client d’une solution Blazor hébergée.
  • SERVEUR : les applications ASP.NET Core server API/web API ou l’application Server d’une solution Blazor hébergée. Vous pouvez ignorer les conseils SERVEUR tout au long de l’article pour une application Blazor WebAssembly autonome.

Les exemples de cet article tirent parti des nouvelles fonctionnalités .NET/C#. Lors de l’utilisation des exemples avec .NET 7 ou antérieur, des modifications mineures sont requises. Toutefois, les exemples de texte et de code relatifs à l’interaction avec ME-ID et Microsoft Graph sont identiques pour toutes les versions de ASP.NET Core.

Prérequis

Les conseils de cet article implémentent l’API Microsoft Graph conformément aux instructions du Kit de développement logiciel (SDK) Graph dans Utiliser l’API Graph avec ASP.NET Core Blazor WebAssembly. Suivez les instructions d’implémentation du Kit de développement logiciel (SDK) Graph pour configurer l’application et la tester afin de confirmer que l’application peut obtenir des données de l’API Graph pour un compte d’utilisateur de test. En outre, consultez les liens croisés de l’article sur la sécurité de l’API Graph pour passer en revue les concepts de sécurité de Microsoft Graph.

Lorsque vous effectuez des tests avec le Kit de développement logiciel (SDK) Graph localement, nous vous recommandons d’utiliser une nouvelle session de navigateur privée/incognito pour chaque test afin d’éviter que les cookies persistants n’interfèrent avec les tests. Pour plus d’informations, consultez Sécuriser une application autonome ASP.NET Core Blazor WebAssembly avec Microsoft Entra ID.

Portées

Pour autoriser les appels de l’API Microsoft Graph pour les données de profil utilisateur, d’attribution de rôle et d’appartenance à un groupe :

  • Une application CLIENTE est configurée avec l’étendue User.Readdéléguée (https://graph.microsoft.com/User.Read) dans le Portail Azure, car l’accès aux données utilisateur de lecture est déterminé par les étendues accordées (déléguées) à des utilisateurs individuels.
  • Une application SERVEUR est configurée avec l’étendue GroupMember.Read.All de l’application (https://graph.microsoft.com/GroupMember.Read.All) dans le Portail Azure, car l’accès est destiné à l’application pour obtenir des informations sur l’appartenance au groupe, et non en fonction de l’autorisation utilisateur individuelle d’accéder aux données sur les membres du groupe.

Les étendues précédentes sont requises en plus des étendues requises dans les scénarios de déploiement ME-ID décrits précédemment (autonome avec les comptes Microsoft ou autonome avec ME-ID).

Les étendues précédentes sont requises en plus des étendues requises dans les scénarios de déploiement ME-ID décrits par les rubriques répertoriées précédemment (autonome avec les comptes Microsoft, autonome avecME-ID et hébergées avec ME-ID).

Pour plus d’informations, consultez Vue d’ensemble des autorisations et du consentement dans la plateforme d’identités Microsoft et Vue d’ensemble des autorisations Microsoft Graph.

Remarque

Les mots « permission » et « étendue » sont utilisés indifféremment dans le portail Azure et dans différents ensembles de documentation Microsoft et de documentation externe. Cet article utilise le mot « étendue » pour les autorisations attribuées à une application dans le portail Azure.

Attribut des revendications d’appartenance à un groupe

Dans le manifeste de l’application dans le portail Azure pour les applications CLIENT et SERVEUR, définissez groupMembershipClaimsl’attribut sur All. La valeur de All aboutit à l’envoi par ME-ID de tous les groupes de sécurité, groupes de distribution et rôles de l’utilisateur connecté dans la revendication des ID connus (wids) :

  1. Ouvrez l’inscription du portail Azure de l’application.
  2. Sélectionnez Gérer>Manifeste dans la barre latérale.
  3. Recherchez l’attribut groupMembershipClaims.
  4. Définissez la valeur sur All ("groupMembershipClaims": "All").
  5. Cliquez sur le bouton Enregistrer si vous avez apporté des modifications.

Compte d’utilisateur personnalisé

Affectez des utilisateurs à des groupes de sécurité ME-ID et des rôles d’administrateur ME-ID dans le portail Azure.

Les exemples de cet article :

  • Supposons qu’un utilisateur est affecté à ME-ID rôle d’administrateur de facturation dans le locataire ME-ID du portail Azure pour l’autorisation d’accéder aux données d’API du serveur.
  • Utilisez des politiques d’autorisation pour contrôler l’accès au sein des applications CLIENT et SERVEUR .

Dans l’application CLIENT, étendez RemoteUserAccount pour inclure les propriétés pour :

CustomUserAccount.cs:

using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

namespace BlazorSample;

public class CustomUserAccount : RemoteUserAccount
{
    [JsonPropertyName("roles")]
    public List<string>? Roles { get; set; }

    [JsonPropertyName("wids")]
    public List<string>? Wids { get; set; }

    [JsonPropertyName("oid")]
    public string? Oid { get; set; }
}

Ajoutez une référence de package à l’application CLIENT pour Microsoft.Graph.

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.

Ajoutez les classes et la configuration de l’utilitaire du Kit de développement logiciel (SDK) Graph dans les instructions du Kit de développement logiciel (SDK) Graph de l’article Utiliser l’API Graph avec ASP.NET CoreBlazor WebAssembly. Spécifiez l’étendue User.Read du jeton d’accès comme illustré dans l’article avec son exemple de fichier wwwroot/appsettings.json.

Ajoutez la fabrique de compte d’utilisateur personnalisée suivante à l’application CLIENT. La fabrique d’utilisateur personnalisée est utilisée pour établir :

  • Revendications de rôle d’application (appRole) (couvertes dans la section Rôles d’application).
  • Revendications de rôle d’administrateur ME-ID (directoryRole).
  • Exemple de revendications de données de profil utilisateur pour le numéro de téléphone mobile de l’utilisateur (mobilePhone) et l’emplacement du bureau (officeLocation).
  • Revendications de groupe ME-ID (directoryGroup).
  • Un ILogger (logger) pour plus de commodité dans le cas où vous souhaitez enregistrer des informations ou des erreurs.

CustomAccountFactory.cs :

L’exemple suivant suppose que le fichier de paramètres d’application du projet inclut une entrée pour l’URL de base :

{
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com/{VERSION}",
    ...
  }
}

Dans l’exemple précédent, l’espace {VERSION} réservé est la version de l’API MS Graph (par exemple : v1.0).

using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;
using Microsoft.Kiota.Abstractions.Authentication;

namespace BlazorSample;

public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger,
        IConfiguration config)
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger = logger;
    private readonly IServiceProvider serviceProvider = serviceProvider;
    private readonly string? baseUrl = 
        config.GetSection("MicrosoftGraph")["BaseUrl"];

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var initialUser = await base.CreateUserAsync(account, options);

        if (initialUser.Identity is not null &&
            initialUser.Identity.IsAuthenticated)
        {
            var userIdentity = initialUser.Identity as ClaimsIdentity;

            if (userIdentity is not null && !string.IsNullOrEmpty(baseUrl))
            {
                account?.Roles?.ForEach((role) =>
                {
                    userIdentity.AddClaim(new Claim("appRole", role));
                });

                account?.Wids?.ForEach((wid) =>
                {
                    userIdentity.AddClaim(new Claim("directoryRole", wid));
                });

                try
                {
                    var client = new GraphServiceClient(
                        new HttpClient(),
                        serviceProvider
                            .GetRequiredService<IAuthenticationProvider>(),
                        baseUrl);

                    var user = await client.Me.GetAsync();

                    if (user is not null)
                    {
                        userIdentity.AddClaim(new Claim("mobilephone",
                            user.MobilePhone ?? "(000) 000-0000"));
                        userIdentity.AddClaim(new Claim("officelocation",
                            user.OfficeLocation ?? "Not set"));
                    }

                    var requestMemberOf = client.Users[account?.Oid].MemberOf;
                    var memberships = await requestMemberOf.Request().GetAsync();

                    if (memberships is not null)
                    {
                        foreach (var entry in memberships)
                        {
                            if (entry.ODataType == "#microsoft.graph.group")
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryGroup", entry.Id));
                            }
                        }
                    }
                }
                catch (AccessTokenNotAvailableException exception)
                {
                    exception.Redirect();
                }
            }
        }

        return initialUser;
    }
}
using System.Security.Claims;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
using Microsoft.Graph;

namespace BlazorSample;

public class CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger)
    : AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
    private readonly ILogger<CustomAccountFactory> logger = logger;
    private readonly IServiceProvider serviceProvider = serviceProvider;

    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var initialUser = await base.CreateUserAsync(account, options);

        if (initialUser.Identity is not null &&
            initialUser.Identity.IsAuthenticated)
        {
            var userIdentity = initialUser.Identity as ClaimsIdentity;

            if (userIdentity is not null)
            {
                account?.Roles?.ForEach((role) =>
                {
                    userIdentity.AddClaim(new Claim("appRole", role));
                });

                account?.Wids?.ForEach((wid) =>
                {
                    userIdentity.AddClaim(new Claim("directoryRole", wid));
                });

                try
                {
                    var client = ActivatorUtilities
                        .CreateInstance<GraphServiceClient>(serviceProvider);
                    var request = client.Me.Request();
                    var user = await request.GetAsync();

                    if (user is not null)
                    {
                        userIdentity.AddClaim(new Claim("mobilephone",
                            user.MobilePhone ?? "(000) 000-0000"));
                        userIdentity.AddClaim(new Claim("officelocation",
                            user.OfficeLocation ?? "Not set"));
                    }

                    var requestMemberOf = client.Users[account?.Oid].MemberOf;
                    var memberships = await requestMemberOf.Request().GetAsync();

                    if (memberships is not null)
                    {
                        foreach (var entry in memberships)
                        {
                            if (entry.ODataType == "#microsoft.graph.group")
                            {
                                userIdentity.AddClaim(
                                    new Claim("directoryGroup", entry.Id));
                            }
                        }
                    }
                }
                catch (AccessTokenNotAvailableException exception)
                {
                    exception.Redirect();
                }
            }
        }

        return initialUser;
    }
}

Le code précédent n’inclut pas d’appartenances transitives. Si l’application nécessite des revendications d’appartenance directe et transitive à un groupe, remplacez la propriété MemberOf (IUserMemberOfCollectionWithReferencesRequestBuilder) par TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).

Le code précédent ignore les revendications d’appartenance au groupe (groups) qui sont des rôles d’administrateur ME-ID (type#microsoft.graph.directoryRole ), car les valeurs GUID retournées par la plateforme d’identités Microsoft sont des ID d’administrateur ME-ID des ID d’entité et non ID de modèle de rôle. Les ID d’entité ne sont pas stables entre les locataires dans la plateforme d'identités Microsoft et ne doivent pas être utilisés pour créer des politiques d’autorisation pour les utilisateurs dans les applications. Utilisez toujours les ID de modèle de rôle pour les rôles d’administrateur ME-ID fournis par wids revendications.

Dans l’application CLIENT, configurez l’authentification MSAL pour utiliser la fabrique de compte d’utilisateur personnalisée.

Vérifiez que le fichier Program utilise l’espace de noms Microsoft.AspNetCore.Components.WebAssembly.Authentication :

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Mettez à jour l’appel AddMsalAuthentication de la manière suivante. Notez que le RemoteUserAccount de l’infrastructure Blazor est remplacé par le CustomUserAccount de l’application pour l’authentification MSAL et la fabrique principale des revendications de compte :

builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
    CustomUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd",
            options.ProviderOptions.Authentication);
    })
    .AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
        CustomAccountFactory>();

Vérifiez la présence du code du Kit de développement logiciel (SDK) Graph décrit par l’article Utiliser l’API Graph avec ASP.NET Core Blazor WebAssembly et vérifiez que la configuration wwwroot/appsettings.json est correcte conformément aux instructions du Kit de développement logiciel (SDK) Graph :

var baseUrl = string.Join("/", 
    builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"], 
    builder.Configuration.GetSection("MicrosoftGraph")["Version"]);
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
    .Get<List<string>>();

builder.Services.AddGraphClient(baseUrl, scopes);

wwwroot/appsettings.json :

{
  "MicrosoftGraph": {
    "BaseUrl": "https://graph.microsoft.com",
    "Version: "v1.0",
    "Scopes": [
      "user.read"
    ]
  }
}

Configuration de l’autorisation

Dans l'application CLIENT, créez une stratégie pour chaque rôle d'application, rôle d'administrateur ME-ID ou groupe de sécurité dans le fichier Program. L’exemple suivant crée une stratégie pour le rôle d’administrateur de facturation ME-ID :

builder.Services.AddAuthorizationCore(options =>
{
    options.AddPolicy("BillingAdministrator", policy => 
        policy.RequireClaim("directoryRole", 
            "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});

Pour obtenir la liste complète des ID pour les rôles d’administrateur ME-ID, consultez ID de modèle de rôle dans la documentation Entra. Pour plus d’informations sur les politiques d’autorisation, consultez Autorisation basée sur des politiques dans ASP.NET Core.

Dans les exemples suivants, l’application CLIENT utilise la politique précédente pour autoriser l’utilisateur.

Le composantAuthorizeView fonctionne avec la politique :

<AuthorizeView Policy="BillingAdministrator">
    <Authorized>
        <p>
            The user is in the 'Billing Administrator' ME-ID Administrator Role
            and can see this content.
        </p>
    </Authorized>
    <NotAuthorized>
        <p>
            The user is NOT in the 'Billing Administrator' role and sees this
            content.
        </p>
    </NotAuthorized>
</AuthorizeView>

L’accès à un composant entier peut être basé sur la politique à l’aide d’une directive d’attribut[Authorize] (AuthorizeAttribute) :

@page "/"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "BillingAdministrator")]

Si l’utilisateur n’est pas autorisé, il est redirigé vers la page de connexion ME-ID.

Une vérification de politique peut également être effectuée dans le code avec une logique procédurale.

CheckPolicy.razor :

@page "/checkpolicy"
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

<h1>Check Policy</h1>

<p>This component checks a policy in code.</p>

<button @onclick="CheckPolicy">Check 'BillingAdministrator' policy</button>

<p>Policy Message: @policyMessage</p>

@code {
    private string policyMessage = "Check hasn't been made yet.";

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

    private async Task CheckPolicy()
    {
        var user = (await authenticationStateTask).User;

        if ((await AuthorizationService.AuthorizeAsync(user, 
            "BillingAdministrator")).Succeeded)
        {
            policyMessage = "Yes! The 'BillingAdministrator' policy is met.";
        }
        else
        {
            policyMessage = "No! 'BillingAdministrator' policy is NOT met.";
        }
    }
}

Autoriser l’accès à l’API serveur/API web

Une application API SERVER peut autoriser les utilisateurs à accéder à des points de terminaison d’API sécurisés avec stratégies d’autorisation pour les groupes de sécurité, les rôles d’administrateur ME-ID et les rôles d’application lorsqu’un jeton d’accès contient les revendications groups, widset role. L'exemple suivant crée une stratégie pour le rôle d'administrateur de facturation ME-ID dans le fichier Program à l'aide des revendications wids (ID bien connus/ID de modèle de rôle) :

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("BillingAdministrator", policy => 
        policy.RequireClaim("wids", "b0f54661-2d74-4c50-afa3-1ec803f12efe"));
});

Pour obtenir la liste complète des ID pour les rôles d’administrateur ME-ID, consultez ID de modèle de rôle dans la documentation Azure. Pour plus d’informations sur les politiques d’autorisation, consultez Autorisation basée sur des politiques dans ASP.NET Core.

L’accès à un contrôleur dans l’application SERVEUR peut être basé sur l’utilisation d’un attribut[Authorize] portant le nom de la politique (documentation de l’API : AuthorizeAttribute).

L’exemple suivant limite l’accès aux données de facturation du BillingDataController aux Administrateurs de facturation Azure avec un nom de politique :BillingAdministrator

using Microsoft.AspNetCore.Authorization;
[Authorize(Policy = "BillingAdministrator")]
[ApiController]
[Route("[controller]")]
public class BillingDataController : ControllerBase
{
    ...
}

Pour plus d’informations, consultez Autorisation basée sur une stratégie dans ASP.NET Core.

Rôles d'application

Pour configurer l’application dans le portail Azure afin de fournir des revendications d’appartenance aux rôles d’application, consultez Ajouter des rôles d’application dans votre application et les recevoir dans le jeton dans la documentation Entra.

L’exemple suivant suppose que les applications CLIENT et SERVEUR sont configurées avec deux rôles et que les rôles sont attribués à un utilisateur de test :

  • Admin
  • Developer

Remarque

Lors du développement d’une paire client-serveur d’applications autonomes (une application Blazor WebAssembly autonome et une application API serveur/API Web ASP.NET Core), la propriété manifeste appRoles des inscriptions d’applications du portail Azure client et serveur doit inclure les mêmes rôles configurés. Après avoir établi les rôles dans le manifeste de l’application cliente, copiez-les dans leur intégralité dans le manifeste de l’application serveur. Si vous ne mettez pas en miroir le manifeste appRoles entre les inscriptions des applications client et serveur, les revendications de rôle ne sont pas établies pour les utilisateurs authentifiés de l’API serveur/API web, même si leur jeton d’accès contient les entrées correctes dans les revendications role.

Remarque

Lors du développement d’une application Blazor WebAssembly hébergée ou d’une paire client-serveur d’applications autonomes (une application Blazor WebAssembly autonome et une application ASP.NET Core server API/web API), la propriété manifeste appRoles du client et des inscriptions d’applications du portail Azure serveur doit inclure les mêmes rôles configurés. Après avoir établi les rôles dans le manifeste de l’application cliente, copiez-les dans leur intégralité dans le manifeste de l’application serveur. Si vous ne mettez pas en miroir le manifeste appRoles entre les inscriptions des applications client et serveur, les revendications de rôle ne sont pas établies pour les utilisateurs authentifiés de l’API serveur/API web, même si leur jeton d’accès contient les entrées correctes dans les revendications role.

Bien que vous ne puissiez pas attribuer de rôles à des groupes sans compte Microsoft Entra ID Premium, vous pouvez attribuer des rôles aux utilisateurs et recevoir une revendication role pour les utilisateurs disposant d’un compte Azure standard. Les conseils de cette section ne nécessitent pas de compte ME-ID Premium.

Si vous disposez d’un compte Azure de niveau Premium, Gérer>Rôles d’application s’affiche dans la barre latérale d’inscription de l’application du portail Azure. Suivez les instructions dans Ajouter des rôles d’application dans votre application et les recevoir dans le jeton pour configurer les rôles de l’application.

Si vous n’avez pas de compte Azure de niveau Premium, modifiez le manifeste de l’application dans le portail Azure. Suivez les instructions de rôles d’application : implémentation pour établir manuellement les rôles de l’application dans l’entrée appRoles du fichier manifeste. Enregistrez les modifications dans le fichier.

Voici un exemple d’entrée appRoles qui crée des rôles Admin et Developer. Ces exemples de rôles sont utilisés plus loin dans l’exemple de cette section au niveau du composant pour implémenter des restrictions d’accès :

"appRoles": [
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Administrators manage developers.",
    "displayName": "Admin",
    "id": "584e483a-7101-404b-9bb1-83bf9463e335",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Admin"
  },
  {
    "allowedMemberTypes": [
      "User"
    ],
    "description": "Developers write code.",
    "displayName": "Developer",
    "id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
    "isEnabled": true,
    "lang": null,
    "origin": "Application",
    "value": "Developer"
  }
],

Pour attribuer un rôle à un utilisateur (ou à un groupe si vous disposez d’un compte Azure de niveau Premium) :

  1. Accédez à applications d’entreprise dans la zone ME-ID du portail Azure.
  2. Sélectionnez l’application. Sélectionnez Gérer>Utilisateurs et groupes dans la barre latérale.
  3. Cochez la case pour un ou plusieurs comptes d’utilisateur.
  4. Dans le menu situé au-dessus de la liste des utilisateurs, sélectionnez Modifier l’affectation.
  5. Pour l’entrée Sélectionner un rôle, sélectionnez Aucun sélectionné.
  6. Choisissez un rôle dans la liste et utilisez le bouton Sélectionner pour le sélectionner.
  7. Utilisez le bouton Attribuer en bas de l’écran pour attribuer le rôle.

Plusieurs rôles sont attribués dans le portail Azure en ajoutant un utilisateur pour chaque attribution de rôle supplémentaire. Utilisez le bouton Ajouter un utilisateur/groupe en haut de la liste des utilisateurs pour rajouter un utilisateur. Utilisez les étapes précédentes pour attribuer un autre rôle à l’utilisateur. Vous pouvez répéter ce processus autant de fois que nécessaire pour ajouter des rôles supplémentaires à un utilisateur (ou un groupe).

Le CustomAccountFactory indiqué dans la section Compte d’utilisateur personnalisé est configuré pour agir sur une revendication role avec une valeur de tableau JSON. Ajoutez et inscrivez le CustomAccountFactory dans l’application CLIENT, comme indiqué dans la section Compte d’utilisateur personnalisé. Il n’est pas nécessaire de fournir du code pour supprimer la revendication role d’origine, car elle est automatiquement supprimée par l’infrastructure.

Dans le fichier Program d'une application CLIENT, précisez la revendication nommée "appRole" comme revendication de rôle pour les contrôles ClaimsPrincipal.IsInRole :

builder.Services.AddMsalAuthentication(options =>
{
    ...

    options.UserOptions.RoleClaim = "appRole";
});

Remarque

Si vous préférez utiliser la revendication directoryRoles (AJOUTER des rôles d’administrateur), attribuez « directoryRoles » au RemoteAuthenticationUserOptions.RoleClaim.

Dans le fichier Program d'une application SERVEUR, spécifiez la revendication nommée "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" comme revendication de rôle pour les contrôles ClaimsPrincipal.IsInRole :

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(options =>
    {
        Configuration.Bind("AzureAd", options);
        options.TokenValidationParameters.RoleClaimType = 
            "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
    },
    options => { Configuration.Bind("AzureAd", options); });

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

Remarque

Si vous préférez utiliser la revendication wids (AJOUTER des rôles d’administrateur), attribuez « wids » au TokenValidationParameters.RoleClaimType.

Une fois que vous avez effectué les étapes précédentes pour créer et attribuer des rôles à des utilisateurs (ou des groupes si vous disposez d’un compte Azure de niveau Premium) et que vous avez implémenté le CustomAccountFactory avec le Kit de développement logiciel (SDK) Graph, comme expliqué plus haut dans cet article et dans Utiliser l’API Graph avec ASP.NET Core Blazor WebAssembly, vous devez voir une revendication appRole pour chaque rôle attribué auquel un utilisateur connecté est affecté (ou les rôles attribués aux groupes dont il est membre). Exécutez l’application avec un utilisateur de test pour vérifier que la ou les revendications sont présentes comme prévu. Lorsque vous effectuez des tests avec le Kit de développement logiciel (SDK) Graph localement, nous vous recommandons d’utiliser une nouvelle session de navigateur privée/incognito pour chaque test afin d’éviter que les cookies persistants n’interfèrent avec les tests. Pour plus d’informations, consultez Sécuriser une application autonome ASP.NET Core Blazor WebAssembly avec Microsoft Entra ID.

Les approches d’autorisation des composants sont fonctionnelles à ce stade. Tous les mécanismes d’autorisation dans les composants de l’application CLIENT peuvent utiliser le rôle Admin pour autoriser l’utilisateur :

Plusieurs tests de rôle sont pris en charge :

  • Exiger que l’utilisateur soit dans le rôle Admin ou Developer avec le composant AuthorizeView :

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • Exiger que l’utilisateur soit à la fois dans les rôles Admin et Developer avec le composant AuthorizeView :

    <AuthorizeView Roles="Admin">
        <AuthorizeView Roles="Developer" Context="innerContext">
            ...
        </AuthorizeView>
    </AuthorizeView>
    

    Pour plus d'informations sur Context pour le AuthorizeView interne, voir ASP.NET CoreBlazor authentification et autorisation.

  • Exiger que l’utilisateur soit dans le rôle Admin ou Developer avec l’attribut [Authorize] :

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • Exiger que l’utilisateur soit à la fois dans les rôles Admin et Developer avec l’attribut [Authorize] :

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • Exiger que l’utilisateur soit dans le rôle Admin ou Developer avec du code procédural :

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • Exiger que l’utilisateur soit à la fois dans les rôles Admin et Developer avec du code procédural en remplaçant le conditionnel OU (||) par un conditionnel ET (&&) dans l’exemple précédent :

    if (user.IsInRole("Admin") && user.IsInRole("Developer"))
    

Tous les mécanismes d’autorisation dans les contrôleurs de l’application SERVEUR peuvent utiliser le rôle Admin pour autoriser l’utilisateur :

Plusieurs tests de rôle sont pris en charge :

  • Exiger que l’utilisateur soit dans le rôle Admin ou Developer avec l’attribut [Authorize] :

    [Authorize(Roles = "Admin, Developer")]
    
  • Exiger que l’utilisateur soit à la fois dans les rôles Admin et Developer avec l’attribut [Authorize] :

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • Exiger que l’utilisateur soit dans le rôle Admin ou Developer avec du code procédural :

    static readonly string[] scopeRequiredByApi = new string[] { "API.Access" };
    
    ...
    
    [HttpGet]
    public IEnumerable<ReturnType> Get()
    {
        HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
    
        if (User.IsInRole("Admin") || User.IsInRole("Developer"))
        {
            ...
        }
        else
        {
            ...
        }
    
        return ...
    }
    
  • Exiger que l’utilisateur soit à la fois dans les rôles Admin et Developer avec du code procédural en remplaçant le conditionnel OU (||) par un conditionnel ET (&&) dans l’exemple précédent :

    if (User.IsInRole("Admin") && User.IsInRole("Developer"))
    

Étant donné que les comparaisons de chaînes .NET respectent la casse par défaut, les noms de rôle correspondants respectent également 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 (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 est également inhabituelle, mais autorisée. Par exemple, billing administrator est un format de nom de rôle inhabituel dans les applications .NET, mais valide.

Ressources supplémentaires