Grupos do Microsoft Entra (ME-ID), Funções de Administrador e Funções de Aplicativo

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Este artigo explica como configurar Blazor WebAssembly para usar grupos e funções do Microsoft Entra ID.

O Microsoft Entra (ME-ID) fornece várias abordagens de autorização que podem ser combinadas com ASP.NET Core Identity:

  • Grupos
    • Segurança
    • Microsoft 365
    • Distribuição
  • Funções
    • Funções de administrador do ME-ID
    • Funções de Aplicativo

As diretrizes neste artigo se aplicam aos cenários de implantação do ME-ID Blazor WebAssembly descritos nos seguintes tópicos:

As diretrizes do artigo fornecem instruções para aplicativos cliente e servidor:

  • CLIENTE: aplicativos Blazor WebAssembly autônomos.
  • SERVIDOR: aplicativos de API/API Web do servidor do ASP.NET Core. Você pode ignorar as diretrizes do SERVER ao longo do artigo para um aplicativo Blazor WebAssembly autônomo.
  • CLIENT: aplicativos Blazor WebAssembly autônomos ou o aplicativo Client de uma Blazorsolução hospedada.
  • SERVER: aplicativos de API web/API do servidor do ASP.NET Core ou o aplicativo Server de uma solução Blazor hospedada. Você pode ignorar as diretrizes do SERVER ao longo do artigo para um aplicativo Blazor WebAssembly autônomo.

Os exemplos deste artigo aproveitam os novos recursos do .NET/C#. Quando você usar os exemplos com o .NET 7 ou versões anteriores, pequenas modificações serão necessárias. No entanto, os exemplos de texto e código que pertencem à interação com o ME-ID e o Microsoft Graph são os mesmos para todas as versões do ASP.NET Core.

Pré-requisito

As diretrizes neste artigo implementam a API do Microsoft Graph de acordo com as diretrizes do SDK do Graph em Usar a API do Graph com ASP.NET Core Blazor WebAssembly. Siga as diretrizes de implementação do SDK do Graph para configurar o aplicativo e testá-lo para confirmar se o aplicativo pode obter dados da API do Graph para uma conta de usuário de teste. Além disso, consulte os links cruzados do artigo de segurança do artigo API do Graph para examinar os conceitos de segurança do Microsoft Graph.

Ao testar com o SDK do Graph localmente, recomendamos usar uma nova sessão anônima/privada do navegador para cada teste para evitar que os cookie persistentes interfiram nos testes. Para obter mais informações, consulte Proteger um aplicativo autônomo ASP.NET Core Blazor WebAssembly com contas do Microsoft Entra ID.

Escopos

Para permitir chamadas à API do Microsoft Graph para dados de perfil de usuário, atribuição de função e associação de grupo:

  • Um aplicativo CLIENTE é configurado com o escopo delegadoUser.Read (https://graph.microsoft.com/User.Read) no portal do Azure porque o acesso aos dados de usuário de leitura é determinado pelos escopos concedidos (delegados) a usuários individuais.
  • Um aplicativo SERVIDOR é configurado com o escopo do aplicativoGroupMember.Read.All (https://graph.microsoft.com/GroupMember.Read.All) no portal do Azure porque o acesso é para o aplicativo obter informações sobre associação de grupo, não com base na autorização individual do usuário para acessar dados sobre membros do grupo.

Os escopos anteriores são exigidos além dos escopos exigidos nos cenários de implantação do ME-ID descritos nos tópicos listados anteriormente (Autônomo com contas Microsoft ou Autônomo com ME-ID).

Os escopos anteriores são necessários além dos escopos obrigatórios em cenários de implantação do ME-ID descritos pelos tópicos listados anteriormente (Autônomo com Contas da Microsoft, Autônomo com ME-ID e Hospedado com ME-ID).

Para obter mais informações, consulte Visão geral das permissões e consentimento na plataforma de identidade da Microsoft e Visão geral das permissões do Microsoft Graph.

Observação

As palavras "permissão" e "escopo" são usadas de forma intercambiável no portal do Azure e em vários conjuntos de documentação da Microsoft e externos. Este artigo usa a palavra "escopo" para as permissões atribuídas a um aplicativo no portal do Azure.

Atributo Declarações de associação de grupo

No manifesto do aplicativo no portal do Azure para aplicativos CLIENT e SERVER, defina o atributo groupMembershipClaims como All. Um valor de All resulta no envio pelo ME-ID de todos os grupos de segurança, grupos de distribuição e funções do usuário conectado na declaração de IDs conhecida (wids):

  1. Abra o registro do portal do Azure do aplicativo.
  2. Selecione Gerenciar>Manifesto na barra lateral.
  3. Localize o atributo groupMembershipClaims.
  4. Defina o valor como All ("groupMembershipClaims": "All").
  5. Selecione o botão Salvar se você fez alterações.

Conta de usuário personalizada

Atribua usuários a grupos de segurança do ME-ID e funções de administrador do ME-ID no portal do Azure.

Os exemplos neste artigo:

  • Pressupõem que um usuário seja atribuído à função Administrador de cobrança do ME-ID no locatário do ME-ID do portal do Azure para autorização para acessar dados da API do servidor.
  • Use políticas de autorização para controlar o acesso nos aplicativos CLIENT e SERVER.

No aplicativo CLIENT, estenda RemoteUserAccount para incluir propriedades para:

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

Adicione uma referência de pacote ao aplicativo CLIENT para Microsoft.Graph.

Observação

Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

Adicione as classes e a configuração do utilitário do SDK do Graph nas diretrizes do SDK do Graph do artigo Usar A API do Graph com ASP.NET CoreBlazor WebAssembly. Especifique o escopo User.Read do token de acesso, como mostra o artigo em seu arquivo de exemplo wwwroot/appsettings.json.

Adicione a fábrica de contas de usuário personalizada a seguir ao aplicativo CLIENT. A fábrica de usuários personalizada é usada para estabelecer:

  • Declarações de Função de Aplicativo (appRole) (abordadas na seção Funções de Aplicativo).
  • Declarações de função de administrador do ME-ID (directoryRole).
  • Exemplo de declarações de dados de perfil de usuário para o número de telefone celular do usuário (mobilePhone) e o local do escritório (officeLocation).
  • Declarações de grupo do ME-ID (directoryGroup).
  • Um ILogger (logger) para conveniência, caso você deseje registrar informações ou erros.

CustomAccountFactory.cs:

O exemplo abaixo pressupõe que o arquivo de configurações do aplicativo do projeto inclui uma entrada para a URL base:

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

No exemplo anterior, o espaço reservado {VERSION} é a versão da API do MS Graph (por exemplo: 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;
    }
}

O código anterior não inclui associações transitivas. Se o aplicativo exigir declarações de associação de grupo diretas e transitivas, substitua a propriedade MemberOf (IUserMemberOfCollectionWithReferencesRequestBuilder) por TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).

O código anterior ignora declarações de associação de grupo (groups) que são Funções de Administrador do ME-ID (tipo #microsoft.graph.directoryRole) porque os valores GUID retornados pelo plataforma de identidade da Microsoft são IDs de entidade de função de administrador do ME-ID e não IDs de modelo de função. As IDs de entidade não são estáveis entre locatários no plataforma de identidade da Microsoft e não devem ser usadas para criar políticas de autorização para usuários em aplicativos. Sempre use IDs de modelo de função para funções de administrador do ME-ID fornecidas por declarações wids.

No aplicativo CLIENT, configure a autenticação MSAL para usar o alocador de contas de usuário personalizado.

Confirme se o arquivo Program usa o namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

Atualize a chamada AddMsalAuthentication para o seguinte. Observe que o RemoteUserAccount da estrutura Blazor é substituído pelo CustomUserAccount do aplicativo para a fábrica de entidades de segurança de declarações de conta e autenticação da MSAL:

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

Confirme a presença do código do SDK do Graph descrito pelo artigo Usar API do Graph com ASP.NET Core Blazor WebAssembly e se a configuração wwwroot/appsettings.json está correta de acordo com as diretrizes do SDK do 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"
    ]
  }
}

Configuração de autorização

No aplicativo CLIENTE, crie uma política para cada função de aplicativo, função de administrador ME-ID ou grupo de segurança no arquivo Program. O exemplo a seguir cria uma política para a função Administrador de cobrança do ME-ID:

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

Para obter a lista completa de IDs para funções de administrador ME-ID, confira IDs de modelo de função na documentação do Entra. Para obter mais informações sobre as políticas de autorização, consulte Autorização baseada em política no ASP.NET Core.

Nos exemplos a seguir, o aplicativo CLIENT usa a política anterior para autorizar o usuário.

O componente AuthorizeView funciona com a política:

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

O acesso a um componente inteiro pode ser baseado na política usando uma diretiva de atributo [Authorize] (AuthorizeAttribute):

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

Se o usuário não estiver autorizado, ele será redirecionado para a página de entrada do ME-ID.

Uma verificação de política também pode ser executada no código com lógica de procedimento.

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

Autorizar o acesso à API Web/API do servidor

Um aplicativo de API SERVER pode autorizar os usuários a acessar pontos de extremidade de API seguros com políticas de autorização para grupos de segurança, Funções de Administrador do ME-ID e Funções de Aplicativo quando um token de acesso contém declarações groups, wids e role. O exemplo a seguir cria uma política para a função administrador de cobrança ME-ID no arquivo Program usando as declarações wids (IDs conhecidas/IDs de modelo de função):

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

Para obter a lista completa de IDs para Funções de Administrador do ME-ID, consulte IDs de modelo de função na documentação do Azure. Para obter mais informações sobre as políticas de autorização, consulte Autorização baseada em política no ASP.NET Core.

O acesso a um controlador no aplicativo SERVER pode ser baseado no uso de um atributo [Authorize] com o nome da política (documentação da API: AuthorizeAttribute).

O exemplo a seguir limita o acesso aos dados de cobrança do BillingDataController para administradores de cobrança do Azure com um nome de política de BillingAdministrator:

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

Para obter mais informações, consulte Autorização baseada em política no ASP.NET Core.

Funções de Aplicativo

Para configurar o aplicativo no portal do Microsoft Azure para fornecer declarações de associação de funções de aplicativo, consulte Adicionar funções de aplicativo ao seu aplicativo e recebê-las no token na documentação do Entra.

O exemplo a seguir pressupõe que os aplicativos CLIENT e SERVER estão configurados com duas funções atribuídas a um usuário de teste:

  • Admin
  • Developer

Observação

Ao desenvolver um par cliente-servidor de aplicativos autônomos (um aplicativo autônomo Blazor WebAssembly e uma API do servidor ASP.NET Core/aplicativo de API Web), a propriedade de manifesto appRoles dos registros de aplicativo do portal do Azure do cliente e do servidor deve incluir as mesmas funções configuradas. Depois de estabelecer as funções no manifesto do aplicativo cliente, copie-as na íntegra para o manifesto do aplicativo servidor. Se você não espelhar o manifesto appRoles entre os registros de aplicativo do cliente e do servidor, as declarações de função não serão estabelecidas para usuários autenticados da API do servidor/API Web, mesmo que seu token de acesso tenha as entradas corretas nas declarações role.

Observação

Ao desenvolver um aplicativo Blazor WebAssembly hospedado ou um par cliente-servidor de aplicativos autônomos (um aplicativo Blazor WebAssembly autônomo e um aplicativo de API web/API do servidor ASP.NET Core), a propriedade de manifesto appRoles dos registros de aplicativo do portal do Azure do cliente e do servidor deve incluir as mesmas funções configuradas. Depois de estabelecer as funções no manifesto do aplicativo cliente, copie-as na íntegra para o manifesto do aplicativo servidor. Se você não espelhar o manifesto appRoles entre os registros de aplicativo do cliente e do servidor, as declarações de função não serão estabelecidas para usuários autenticados da API do servidor/API Web, mesmo que seu token de acesso tenha as entradas corretas nas declarações role.

Embora não seja possível atribuir funções a grupos sem uma conta Microsoft Entra ID Premium, você pode atribuir funções aos usuários e receber uma declaração role para usuários com uma conta padrão do Azure. As diretrizes nesta seção não exigem uma conta Premium do ME-ID.

Se você tiver uma conta do Azure de camada Premium, Gerenciar>Funções de aplicativo aparecerá na barra lateral de registro do aplicativo do portal do Azure. Siga as diretrizes em Adicionar funções de aplicativo ao seu aplicativo e receba-as no token para configurar as funções do aplicativo.

Se você não tiver uma conta do Azure de camada Premium, edite o manifesto do aplicativo no portal do Azure. Siga as diretrizes em Funções de aplicativo: Implementação para estabelecer as funções do aplicativo manualmente na entrada appRoles do arquivo de manifesto. Salve as alterações no arquivo.

Veja a seguir uma entrada de exemplo appRoles que cria funções Admin e Developer. Essas funções de exemplo são usadas posteriormente no exemplo desta seção no nível do componente para implementar restrições de acesso:

"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 atribuir uma função a um usuário (ou grupo, se você tiver uma conta do Azure de camada Premium):

  1. Acesse Aplicativos empresariais na área do ME-ID do portal do Azure.
  2. Selecione o aplicativo. Selecione Gerenciar>Usuários e grupos na barra lateral.
  3. Marque a caixa de seleção para uma ou mais contas de usuário.
  4. No menu acima da lista de usuários, selecione Editar atribuição.
  5. Para a entrada Selecionar uma função, selecione Nenhuma selecionada.
  6. Escolha uma função na lista e use o botão Selecionar para selecioná-la.
  7. Use o botão Atribuir na parte inferior da tela para atribuir a função.

Várias funções são atribuídas no portal do Azure adicionando novamente um usuário para cada atribuição de função adicional. Use o botão Adicionar usuário/grupo na parte superior da lista de usuários para adicionar novamente um usuário. Use as etapas anteriores para atribuir outra função ao usuário. Você pode repetir esse processo quantas vezes forem necessárias para adicionar funções adicionais a um usuário (ou grupo).

O CustomAccountFactory mostrado na seção Conta de usuário personalizada é configurado para agir em uma declaração role com um valor de matriz JSON. Adicione e registre o CustomAccountFactory no aplicativo CLIENT, conforme mostrado na seção Conta de usuário personalizada. Não é necessário fornecer código para remover a declaração role original porque ela é removida automaticamente pela estrutura.

No arquivo Program de um aplicativo CLIENTE, especifique a declaração chamada "appRole" como a declaração de função para as verificações ClaimsPrincipal.IsInRole:

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

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

Observação

Se você preferir usar a declaração directoryRoles (Funções de Administrador ADD), atribua "directoryRoles" ao RemoteAuthenticationUserOptions.RoleClaim.

No arquivo Program de um aplicativo SERVIDOR, especifique a declaração chamada "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" como a declaração de função para verificações 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); });

Observação

Quando um único esquema de autenticação é registrado, o esquema de autenticação é usado automaticamente como o esquema padrão do aplicativo e não é necessário declarar o esquema para AddAuthentication ou por meio de AuthenticationOptions. Para obter mais informações, consulte Visão geral da Autenticação ASP.NET Core e o comunicado de ASP.NET Core (aspnet/Announcements #490).

Observação

Se você preferir usar a declaração wids (Funções de Administrador ADD), atribua "wids" ao TokenValidationParameters.RoleClaimType.

Depois de concluir as etapas anteriores para criar e atribuir funções a usuários (ou grupos, se você tiver uma conta do Azure de camada Premium) e implementar o CustomAccountFactory com o SDK do Graph, conforme explicado anteriormente neste artigo e em Usar API do Graph com ASP.NET Core Blazor WebAssembly, você deverá ver uma declaração appRole para cada função atribuída à qual um usuário conectado é atribuído (ou funções atribuídas a grupos dos quais eles são membros). Execute o aplicativo com um usuário de teste para confirmar se as declarações estão presentes conforme o esperado. Ao testar com o SDK do Graph localmente, recomendamos usar uma nova sessão anônima/privada do navegador para cada teste para evitar que os cookie persistentes interfiram nos testes. Para obter mais informações, consulte Proteger um aplicativo autônomo ASP.NET Core Blazor WebAssembly com contas do Microsoft Entra ID.

As abordagens de autorização de componentes estão funcionais neste momento. Qualquer um dos mecanismos de autorização em componentes do aplicativo CLIENT pode usar a função Admin para autorizar o usuário:

Há suporte para vários testes de função:

  • Exige que o usuário esteja na função AdminouDeveloper com o componente AuthorizeView:

    <AuthorizeView Roles="Admin, Developer">
        ...
    </AuthorizeView>
    
  • Exige que o usuário esteja nas funções AdmineDeveloper com o componente AuthorizeView:

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

    Para obter mais informações no Context para AuthorizeView interno, confira autenticação e autorização Blazor do ASP.NET Core.

  • Exige que o usuário esteja na função AdminouDeveloper com o atributo [Authorize]:

    @attribute [Authorize(Roles = "Admin, Developer")]
    
  • Exige que o usuário esteja nas funções AdmineDeveloper com o atributo [Authorize]:

    @attribute [Authorize(Roles = "Admin")]
    @attribute [Authorize(Roles = "Developer")]
    
  • Exige que o usuário esteja na função AdminouDeveloper com o código de procedimento:

    @code {
        private async Task DoSomething()
        {
            var authState = await AuthenticationStateProvider
                .GetAuthenticationStateAsync();
            var user = authState.User;
    
            if (user.IsInRole("Admin") || user.IsInRole("Developer"))
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
    
  • Exija que o usuário esteja nas funções AdmineDeveloper com código de procedimento alterando o OR condicional (||) para um AND condicional (&&) no exemplo anterior:

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

Qualquer um dos mecanismos de autorização em controladores do aplicativo SERVER pode usar a função Admin para autorizar o usuário:

Há suporte para vários testes de função:

  • Exige que o usuário esteja na função AdminouDeveloper com o atributo [Authorize]:

    [Authorize(Roles = "Admin, Developer")]
    
  • Exige que o usuário esteja nas funções AdmineDeveloper com o atributo [Authorize]:

    [Authorize(Roles = "Admin")]
    [Authorize(Roles = "Developer")]
    
  • Exige que o usuário esteja na função AdminouDeveloper com o código de procedimento:

    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 ...
    }
    
  • Exija que o usuário esteja nas funções AdmineDeveloper com código de procedimento alterando o OR condicional (||) para um AND condicional (&&) no exemplo anterior:

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

Como as comparações de cadeia de caracteres do .NET diferenciam maiúsculas de minúsculas por padrão, a correspondência de nomes de função também diferencia maiúsculas de minúsculas. Por exemplo, Admin (A em maiúsculas) não é tratado como a mesma função que admin (a em minúsculas).

O caso Pascal normalmente é usado para nomes de função (por exemplo, BillingAdministrator), mas o uso do caso Pascal não é um requisito estrito. Diferentes esquemas de uso de maiúsculas e minúsculas, como maiúsculas e minúsculas concatenadas, kebab e snake são permitidos. O uso de espaços em nomes de função também é incomum, mas permitido. Por exemplo, billing administrator é um formato de nome de função incomum em aplicativos .NET, mas válido.

Recursos adicionais