Grupos de Microsoft Entra (ME-ID), Roles de Administrador y Roles de aplicación

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

En este artículo se explica cómo configurar Blazor WebAssembly para usar grupos y roles de identificadores de Microsoft Entra.

Microsoft Entra (ME-ID) proporciona diversos métodos de autorización que se pueden combinar con ASP.NET Core Identity:

  • Grupos
    • Seguridad
    • Microsoft 365
    • Distribución
  • Roles
    • Roles de Administrador de ME-ID
    • Roles de aplicación

La guía de este artículo atañe a los escenarios de implementación Blazor WebAssembly de ME-ID descritos en:

En la guía del artículo se proporcionan instrucciones para las aplicaciones de cliente y servidor:

  • CLIENTE: aplicaciones Blazor WebAssembly independientes.
  • SERVIDOR: API del servidor ASP.NET Core o aplicaciones de API web. Puede ignorar las instrucciones de SERVIDOR en todo el artículo para una aplicación Blazor WebAssembly independiente.
  • CLIENTE: Aplicaciones Blazor WebAssembly independientes o la aplicación Client de una soluciónBlazor hospedada.
  • SERVIDOR: aplicaciones de API web/API de servidor de ASP.NET Core o la aplicación Server de una solución Blazor hospedada. Puede ignorar las instrucciones de SERVIDOR en todo el artículo para una aplicación Blazor WebAssembly independiente.

Los ejemplos de este artículo aprovechan las nuevas características de .NET/C#. Al usar los ejemplos con .NET 7 o versiones anteriores, se requieren modificaciones menores. Sin embargo, los ejemplos de texto y código que pertenecen a la interacción con ME-ID y Microsoft Graph son los mismos para todas las versiones de ASP.NET Core.

Requisito previo

La guía de este artículo implementa Microsoft Graph API de acuerdo con la guía del SDK de Graph en Uso de Graph API con Blazor WebAssembly de ASP.NET Core. Siga la guía de implementación del SDK de Graph para configurar la aplicación y probarla a fin de confirmar que esta puede obtener datos de Graph API para una cuenta de usuario de prueba. Asimismo, vea los vínculos del artículo de seguridad de Graph API para revisar los conceptos de seguridad de Microsoft Graph.

Al realizar pruebas con el SDK de Graph localmente, le recomendamos que utilice una nueva sesión de explorador privada/de incógnito para cada prueba para evitar que los cookies persistentes interfieran con las pruebas. Para más información, consulte Protección de una aplicación ASP.NET Core Blazor WebAssembly independiente con Cuentas de Microsoft.

Ámbitos

Para permitir que Microsoft Graph API llame a datos de perfil de usuario, asignación de roles y pertenencia a grupos:

  • Una aplicación CLIENTE está configurada con el ámbito delegadoUser.Read (https://graph.microsoft.com/User.Read) en Azure Portal, porque el acceso a la lectura de datos de usuario viene determinado por los ámbitos concedidos (delegados) a usuarios individuales.
  • Una aplicación SERVIDOR está configurada con el ámbito aplicaciónGroupMember.Read.All (https://graph.microsoft.com/GroupMember.Read.All) en Azure Portal porque el acceso es para que la aplicación obtenga información sobre la pertenencia a un grupo, no en función de la autorización individual del usuario para acceder a los datos sobre los miembros del grupo.

Los ámbitos anteriores son necesarios junto con los ámbitos requeridos en los escenarios de implementación de ME-ID que describen los temas enumerados anteriormente (Independiente con Cuentas de Microsoft o Independiente con ME-ID).

Los ámbitos anteriores son necesarios junto con los ámbitos requeridos en los escenarios de implementación de ME-ID que describen los temas enumerados anteriormente (Independiente con Cuentas de Microsoft, Independiente con ME-ID y Hospedado con ME-ID).

Para obtener más información, consulte Información general sobre los permisos y el consentimiento en la Plataforma de identidad de Microsoft e Información general sobre los permisos de Microsoft Graph.

Nota:

Las palabras "permiso" y "ámbito" se usan indistintamente en el Azure Portal y en varios juegos de documentación tanto de Microsoft como externos. En este artículo se utiliza la palabra "ámbito" para hacer referencia a los permisos asignados a una aplicación en Azure Portal.

Atributo de notificaciones de pertenencia a grupos

En el manifiesto de la aplicación de Azure Portal para las aplicaciones CLIENTE y SERVIDOR, establezca el atributo groupMembershipClaims en All. Un valor de All da como resultado que ME-ID envíe todos los grupos de seguridad, de distribución y los roles del usuario que ha iniciado sesión en la notificación de identificadores conocidos (wids):

  1. Abra el registro de Azure Portal de la aplicación.
  2. Seleccione Administrar>Manifiesto en la barra lateral.
  3. Busque el atributo groupMembershipClaims.
  4. Establezca el valor en All ("groupMembershipClaims": "All").
  5. Seleccione el botón Guardar si realizó cambios.

Cuenta de usuario personalizada

Asigne usuarios a grupos de seguridad de ME-ID y Roles de Administrador de ME-ID en Azure Portal.

En los ejemplos de este artículo:

  • Se supone que un usuario tiene asignado el rol de ME-IDAdministrador de facturación en el suscriptor de Azure Portal ME-ID para que tenga autorización y acceder a los datos de la API del servidor.
  • Se usan las directivas de autorización para controlar el acceso dentro de las aplicaciones CLIENTE y SERVIDOR.

En la aplicación CLIENTE, extienda RemoteUserAccount para incluir las propiedades de:

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

Agregue una referencia de paquete a la aplicación CLIENTE para Microsoft.Graph.

Nota

Para obtener instrucciones sobre cómo agregar paquetes a aplicaciones .NET, consulte los artículos de Instalación y administración de paquetes en Flujo de trabajo de consumo de paquetes (NuGet documentación). Confirme las versiones correctas del paquete en NuGet.org.

Agregue la configuración y las clases de utilidad del SDK de Graph de la guía del SDK de Graph del artículo Uso de Graph API con Blazor WebAssembly de ASP.NET Core. Especifique el ámbito User.Read para el token de acceso como muestra el artículo en su archivo wwwroot/appsettings.json de ejemplo.

Agregue la siguiente fábrica de cuentas de usuario personalizada a la aplicación CLIENTE. La fábrica de usuarios personalizada se usa para establecer:

  • Notificaciones de rol de aplicación (appRole) (se trata en la sección Roles de aplicación).
  • Notificaciones de Rol de Administrador de ME-ID (directoryRole).
  • Notificaciones de datos de perfil de usuario de ejemplo para el número de teléfono móvil del usuario (mobilePhone) y la ubicación de la oficina (officeLocation).
  • Notificaciones de Grupo de ME-ID (directoryGroup).
  • Una instancia de ILogger (logger) para mayor comodidad en caso de que quiera registrar información o errores.

CustomAccountFactory.cs:

En el siguiente ejemplo se supone que el archivo de configuración de la aplicación del proyecto incluye una entrada para la dirección URL base:

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

En el ejemplo anterior, el marcador de posición {VERSION} es la versión de MS Graph API (por ejemplo: 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;
    }
}

El código anterior no incluye pertenencias transitivas. Si la aplicación requiere notificaciones directas y transitivas de pertenencia a grupos, reemplace la propiedad MemberOf (IUserMemberOfCollectionWithReferencesRequestBuilder) por TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).

En el código anterior se omiten las notificaciones de pertenencia a grupos (groups) que son Roles de Administrador de ME-ID (tipo #microsoft.graph.directoryRole) porque los valores de GUID que devuelve la plataforma de identidad de Microsoft son Identificadores de entidad del Rol de Administrador de ME-ID y no Identificadores de plantilla de rol. Los identificadores de entidad no son estables entre los inquilinos de la plataforma de identidad de Microsoft y no deben usarse para crear directivas de autorización para los usuarios de las aplicaciones. Use siempre Identificadores de plantilla de rol para Roles de Administrador de ME-ID proporcionados por widsnotificaciones.

En la aplicación CLIENTE, configure la autenticación de MSAL para usar la fábrica de cuentas de usuario personalizada.

Confirme que el archivo Program usa el espacio de nombres Microsoft.AspNetCore.Components.WebAssembly.Authentication:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Actualice la llamada AddMsalAuthentication a lo siguiente. Tenga en cuenta que el elemento RemoteUserAccount del marco de Blazor se reemplaza por el objeto CustomUserAccount de la aplicación para la autenticación de MSAL y la fábrica de entidades de seguridad de notificaciones de cuenta:

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

Confirme la presencia del código del SDK de Graph que se describe en el artículo Uso de Graph API con Blazor WebAssembly de ASP.NET Core y que la configuración de wwwroot/appsettings.json es correcta de acuerdo con la guía del SDK de 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"
    ]
  }
}

Configuración de autorización

En la aplicación CLIENTE, cree una directiva para cada rol de aplicación, rol Administrador de ME-ID, o grupo de seguridad en el archivo Program. En el siguiente ejemplo se crea una directiva para el rol Administrador de facturación de ME-ID:

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

Consulte la lista completa de los identificadores de los roles Administrador de ME-ID en Identificadores de plantilla de rol de la documentación de Entra. Para obtener más información sobre las directivas de autorización, vea Autorización basada en directivas en ASP.NET Core.

En los siguientes ejemplos, la aplicación CLIENTE usa la directiva anterior para autorizar al usuario.

El componente AuthorizeView funciona con la directiva:

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

El acceso a un componente completo se puede basar en la directiva usando una directiva de atributo [Authorize] (AuthorizeAttribute):

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

Si el usuario no está autorizado, se le redirigirá a la página de inicio de sesión de ME-ID.

También se puede realizar una comprobación de directiva en el código con lógica de procedimientos.

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

Autorización del acceso a la API web/API de servidor

Una aplicación de API de SERVIDOR puede autorizar a los usuarios para que accedan a puntos de conexión de API seguros con directivas de autorización para grupos de seguridad, Roles de Administrador de ME-ID y Roles de aplicación cuando un token de acceso contiene notificaciones groups, wids y role. En el ejemplo siguiente, se crea una directiva para el rol Administrador de facturación de ME-ID en el archivo Program con las notificaciones wids (identificadores conocidos e identificadores de plantilla de rol):

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

Consulte la lista completa de los identificadores de los Roles de Administrador de ME-ID enIdentificadores de plantilla de rol de la documentación de Azure. Para obtener más información sobre las directivas de autorización, vea Autorización basada en directivas en ASP.NET Core.

El acceso a un controlador de la aplicación SERVIDOR puede basarse en el uso de un atributo [Authorize] con el nombre de la directiva (documentación de la API: AuthorizeAttribute).

En el siguiente ejemplo se limita el acceso a los datos de facturación del elemento BillingDataController a los administradores de facturación de Azure con un nombre de directiva de BillingAdministrator:

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

Para obtener más información, vea Autorización basada en directivas en ASP.NET Core.

Roles de aplicación

Para configurar la aplicación en Azure Portal para proporcionar notificaciones de pertenencia a roles de aplicación, consulte Incorporación de roles de aplicación a la aplicación y recibirlos en el token en la documentación de Entra.

En el ejemplo siguiente se da por supuesto que las aplicaciones CLIENTE y SERVIDOR están configuradas con dos roles y los roles están asignados a un usuario de prueba:

  • Admin
  • Developer

Nota:

Al desarrollar un par cliente-servidor de aplicaciones independientes (una aplicación Blazor WebAssembly independiente y una API del servidor ASP.NET Core o aplicación de API web), la propiedad del manifiesto appRoles de los registros de aplicaciones de Azure Portal de cliente y servidor deben incluir los mismos roles configurados. Después de establecer los roles en el manifiesto de la aplicación del cliente, cópielos en su totalidad en el manifiesto de la aplicación de servidor. Si no refleja el manifiesto appRoles entre los registros de aplicaciones de cliente y de servidor, las notificaciones de rol no se establecen para los usuarios autenticados de la API web o la API de servidor, aunque su token de acceso tenga las entradas correctas en las notificaciones de role.

Nota:

Al desarrollar una aplicación Blazor WebAssembly hospedada o un par cliente-servidor de aplicaciones independientes (una aplicación Blazor WebAssembly independiente y una aplicación de API web/API de servidor de ASP.NET Core), la propiedad del manifiesto appRoles de los registros de aplicaciones de Azure Portal de cliente y servidor deben incluir los mismos roles configurados. Después de establecer los roles en el manifiesto de la aplicación del cliente, cópielos en su totalidad en el manifiesto de la aplicación de servidor. Si no refleja el manifiesto appRoles entre los registros de aplicaciones de cliente y de servidor, las notificaciones de rol no se establecen para los usuarios autenticados de la API web o la API de servidor, aunque su token de acceso tenga las entradas correctas en las notificaciones de role.

Aunque no se pueden asignar roles a grupos sin una cuenta de Microsoft Entra ID Premium, sí se pueden asignar roles a usuarios y recibir una notificación role para usuarios con una cuenta de Azure estándar. Las instrucciones de esta sección no requieren una cuenta ME-ID Premium.

Si tiene una cuenta de Azure de nivel Premium, Administrar>Roles de aplicación aparece en la barra lateral del registro de aplicaciones de Azure Portal. Siga las instrucciones de Incorporación de roles de aplicación a una aplicación y recibirlos en el token para configurar los roles de la aplicación.

Si no tiene ninguna cuenta de Azure de nivel Premium, edite el manifiesto de la aplicación en Azure Portal. Siga las instrucciones Roles de aplicación: Implementación para establecer de forma manual los roles de la aplicación en la entrada appRoles del archivo de manifiesto. Guarde los cambios en el archivo.

A continuación, se muestra una entrada appRoles de ejemplo que crea los roles Admin y Developer. Estos roles de ejemplo se usan más adelante en el ejemplo de esta sección en el nivel de componente para implementar restricciones de acceso:

"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"
  }
],

Para asignar un rol a un usuario (o a un grupo si tiene una cuenta de Azure de nivel Premium):

  1. Vaya a Aplicaciones empresariales en el área de ME-ID de Azure Portal.
  2. Seleccione la aplicación. Seleccione Administrar>Usuarios y grupos en la barra lateral.
  3. Seleccione la casilla de una o varias cuentas de usuario.
  4. En el menú situado sobre la lista de usuarios, seleccione Editar asignación.
  5. En la entrada Seleccionar un rol, seleccione Ninguno seleccionado.
  6. Elija un rol de la lista y use el botón Seleccionar para seleccionarlo.
  7. Use el botón Asignar situado en la parte inferior de la pantalla para asignar el rol.

Puede asignar varios roles en Azure Portal volviendo a agregar un usuario en cada asignación de rol adicional. Use el botón Agregar usuario o grupo en la parte superior de la lista de usuarios para volver a agregar un usuario. Use los pasos anteriores para asignar otro rol al usuario. Puede repetir este proceso tantas veces como sea necesario para agregar roles adicionales a un usuario (o grupo).

El valor CustomAccountFactory que se muestra en la sección Cuenta de usuario personalizada se configura para que actúe en una notificación de role con un valor de matriz JSON. Agregue y registre CustomAccountFactory en la aplicación CLIENTE como se muestra en la sección Cuenta de usuario personalizada. No es necesario incluir código para quitar la notificación role original, ya que el marco la quitará automáticamente.

En el archivo Program de una aplicación CLIENTE, especifique la notificación denominada "appRole" como la notificación de rol para las comprobaciones ClaimsPrincipal.IsInRole:

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

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

Nota:

Si prefiere usar la notificación directoryRoles (roles de administrador de ADD), asigne "directoryRoles" a RemoteAuthenticationUserOptions.RoleClaim.

En el archivo Program de una aplicación SERVIDOR, especifique la notificación denominada "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" como la notificación de rol para las comprobaciones 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); });

Nota:

Cuando se registra un único esquema de autenticación, se usa automáticamente como esquema predeterminado de la aplicación y no es necesario indicar el esquema a AddAuthentication o a través de AuthenticationOptions. Para obtener más información, consulte:Información general sobre la autenticación de ASP.NET Core y el anuncio de ASP.NET Core (aspnet/Announcements #490).

Nota

Si prefiere usar la notificación wids (roles de administrador de ADD), asigne "wids" a TokenValidationParameters.RoleClaimType.

Una vez que se hayan completado los pasos anteriores para crear y asignar roles a usuarios (o a grupos si tiene una cuenta de Azure de nivel Premium) y se haya implementado CustomAccountFactory con el SDK de Graph, tal y como se explicó anteriormente en este artículo y en Uso de Graph API con Blazor WebAssembly de ASP.NET Core, debería ver una notificación de appRole para cada rol asignado al que se asigna un usuario que ha iniciado sesión (o roles asignados a grupos de los que son miembros). Ejecute la aplicación con un usuario de prueba para confirmar que las notificaciones están presentes según lo previsto. Al realizar pruebas con el SDK de Graph localmente, le recomendamos que utilice una nueva sesión de explorador privada/de incógnito para cada prueba para evitar que los cookies persistentes interfieran con las pruebas. Para más información, consulte Protección de una aplicación ASP.NET Core Blazor WebAssembly independiente con Cuentas de Microsoft.

Los métodos de autorización de componentes son funcionales en este momento. Cualquiera de los mecanismos de autorización de los componentes de la aplicación CLIENTE puede usar el rol Admin para autorizar al usuario:

Se admiten pruebas de rol múltiple:

  • Requiere que el usuario esté en cualquiera de los roles AdminoDeveloper con el componente AuthorizeView:

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • Requiere que el usuario esté en ambos roles AdminyDeveloper con el componente AuthorizeView:

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

    Para obtener más información sobre el Context del AuthorizeView interno, consulte ASP.NET Core Blazor autenticación y autorización.

  • Requiere que el usuario esté en cualquiera de los roles AdminoDeveloper con el atributo [Authorize]:

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • Requiere que el usuario esté en ambos roles AdminyDeveloper con el atributo [Authorize]:

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • Requiere que el usuario esté en cualquiera de los roles AdminoDeveloper con el código de procedimientos:

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • Se requiere que el usuario esté en ambos roles AdminyDeveloper con el código de procedimientos cambiando el OR condicional (||) a un AND condicional (&&) en el ejemplo anterior:

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

Cualquiera de los mecanismos de autorización de los controladores de la aplicación SERVIDOR puede usar el rol Admin para autorizar al usuario:

Se admiten pruebas de rol múltiple:

  • Requiere que el usuario esté en cualquiera de los roles AdminoDeveloper con el atributo [Authorize]:

    [Authorize(Roles = "Admin, Developer")]
    
  • Requiere que el usuario esté en ambos roles AdminyDeveloper con el atributo [Authorize]:

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • Requiere que el usuario esté en cualquiera de los roles AdminoDeveloper con el código de procedimientos:

    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 ...
    }
    
  • Se requiere que el usuario esté en ambos roles AdminyDeveloper con el código de procedimientos cambiando el OR condicional (||) a un AND condicional (&&) en el ejemplo anterior:

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

Dado que las comparaciones de cadenas de .NET distinguen mayúsculas de minúsculas de forma predeterminada, los nombres de rol coincidentes también distinguen mayúsculas de minúsculas. Por ejemplo, Admin (A mayúscula) no se trata como el mismo rol que admin (a minúscula).

Normalmente se usa la notación Pascal Case para los nombres de rol (por ejemplo, BillingAdministrator), pero el uso de Pascal Case no es un requisito estricto. Se permiten diferentes notaciones, como la grafía camel, la grafía kebab y la grafía de serpiente (distintos tipos de uso de mayúsculas y minúsculas y separaciones con guiones). El uso de espacios en nombres de roles también es inusual, pero se permite. Por ejemplo, billing administrator es un formato inusual de nombre de rol en aplicaciones de .NET, pero es válido.

Recursos adicionales