Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Important
Esta não é a versão mais recente deste artigo. Para a versão atual do ASP.NET Core, consulte a versão mais recente do ASP.NET Core Blazor WebAssembly com grupos e funções do Microsoft Entra ID.
Important
O modelo de projeto Hosted Blazor WebAssembly foi removido da estrutura com o lançamento do .NET 8 (novembro de 2023). As orientações neste artigo só são suportadas para o .NET 7 ou anterior. Os aplicativos de Blazor WebAssembly hospedados que são atualizados a cada versão continuam a receber suporte ao produto. Como alternativa, refatore a aplicação numa aplicação Blazor WebAssembly independente ou numa Blazor Web App.
Este artigo explica como configurar Blazor WebAssembly para usar grupos e funções do Microsoft Entra ID.
Microsoft Entra (ME-ID) fornece várias abordagens de autorização que podem ser combinadas com ASP.NET Core Identity:
- Groups
- Segurança
- Microsoft 365
- Distribution
- Roles
- ME-ID Funções de Administrador
- Funções de Aplicação
As diretrizes neste artigo se aplicam aos Blazor WebAssembly cenários de implantação ME-ID descritos nos seguintes artigos:
As diretrizes do artigo fornecem instruções para aplicativos cliente e servidor:
- CLIENTE: Aplicações independentes Blazor WebAssembly ou a Client aplicação de uma Blazorsolução hospedada.
- SERVIDOR: ASP.NET aplicativos de API/API da Web do servidor núcleo ou o Server aplicativo de uma solução hospedada Blazor . Você pode ignorar as orientações do SERVER ao longo do artigo para um aplicativo autônomo Blazor WebAssembly .
Os exemplos neste artigo aproveitam os novos recursos do .NET/C#. Ao usar os exemplos com o .NET 7 ou anterior, pequenas modificações são necessárias. No entanto, o texto e os exemplos de código que dizem respeito à interação com o ME-ID e o Microsoft Graph são os mesmos para todas as versões do ASP.NET Core.
Prerequisite
A orientação neste artigo implementa a API do Microsoft Graph de acordo com a orientação 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 as hiperligações cruzadas do artigo de segurança da Graph API para examinar os conceitos de segurança do Microsoft Graph.
Ao testar com o Graph SDK localmente, recomendamos o uso de uma nova sessão de navegador in-private/incognito para cada teste para evitar que cookies persistentes interfiram nos testes. Para obter mais informações, consulte Proteger um aplicativo autônomo do ASP.NET Core Blazor WebAssembly com o Microsoft Entra ID.
Scopes
Para permitir chamadas da API do Microsoft Graph para dados de perfil de usuário, atribuição de função e associação de grupo:
- Um aplicativo CLIENT é configurado com o escopo delegado
User.Read(https://graph.microsoft.com/User.Read) no portal do Azure porque o acesso à leitura de dados do usuário é determinado pelos escopos concedidos (delegados) a usuários individuais. - Um aplicativo SERVER é configurado com o escopo do aplicativo
GroupMember.Read.All(https://graph.microsoft.com/GroupMember.Read.All) no portal do Azure porque o acesso é para o aplicativo obter informações sobre a associação ao grupo, não com base na autorização de usuário individual para acessar dados sobre membros do grupo.
Os escopos anteriores são necessários, além dos escopos exigidos em cenários de implantação ME-ID descritos pelos artigos 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 de permissões e consentimento na plataforma de identidade da Microsoft e Visão geral das permissões do Microsoft Graph.
Permissões e escopos significam a mesma coisa e são usados de forma intercambiável na documentação de segurança e no portal do Azure. A menos que o texto esteja se referindo ao portal do Azure, este artigo usa escopo/escopos ao referir-se a permissões do Graph.
Os escopos não diferenciam maiúsculas de minúsculas, portanto User.Read é o mesmo que user.read. Sinta-se à vontade para usar qualquer um dos formatos, mas recomendamos uma escolha consistente entre os códigos do aplicativo.
Atributo Declarações de Filiação de Grupo
No manifesto do aplicativo no portal do Azure para aplicativos CLIENT e SERVER , defina o groupMembershipClaims atributo como DirectoryRole. Um valor de DirectoryRole resulta em ME-ID o envio de todos os perfis do utilizador autenticado na declaração de IDs bem conhecidos (wids):
- Abra o registro do portal do Azure do aplicativo.
- Selecione Gerir>Manifesto na barra lateral.
- Encontre o atributo
groupMembershipClaims. - Defina o valor como
DirectoryRole("groupMembershipClaims": "DirectoryRole"). - Selecione o botão Salvar se tiver feito alterações.
No manifesto do aplicativo no portal do Azure para aplicativos CLIENT e SERVER , defina o groupMembershipClaims atributo como All. Um valor de All resulta em ME-ID envia todos os grupos de segurança, grupos de distribuição e funções do utilizador conectado na declaração de IDs bem conhecidos (wids):
- Abra o registro do portal do Azure do aplicativo.
- Selecione Gerir>Manifesto na barra lateral.
- Encontre o atributo
groupMembershipClaims. - Defina o valor como
All("groupMembershipClaims": "All"). - Selecione o botão Salvar se tiver feito alterações.
Conta de utilizador personalizada
Atribua usuários a ME-ID grupos de segurança e ME-ID Funções de Administrador no portal do Azure.
Os exemplos neste artigo:
- Suponha que um utilizador seja atribuído à função de Administrador de Cobrança no locatário ME-ID do portal do Azure ME-ID para autorização para acessar dados da API do servidor.
- Use políticas de autorização para controlar o acesso dentro dos aplicativos CLIENT e SERVER .
No aplicativo CLIENT , estenda RemoteUserAccount para incluir propriedades para:
-
Roles: ME-ID matriz Funções de Aplicativo (abordada na seção Funções de Aplicativo ) -
Wids: ME-ID Funções de administrador na declaração de identificadores conhecidos (wids) -
Oid: Declaração de identificador de objeto imutável (oid) (identifica exclusivamente um usuário dentro e entre locatários)
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.
Note
Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos na seção Instalar e gerenciar pacotes em Workflow de utilização de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.
Adicione as classes de utilitários e a configuração do Graph SDK no guia do Graph SDK do artigo Usar a API do Graph com ASP.NET Core Blazor WebAssembly. Especifique o User.Read escopo para o token de acesso como o artigo mostra em seu arquivo de exemplo wwwroot/appsettings.json .
Adicione a fábrica personalizada de contas de utilizador seguinte ao aplicativo CLIENT. A fábrica de utilizador personalizada é utilizada para estabelecer:
- Declarações de Função de Aplicativo (
appRole) (abordadas na seção Funções de Aplicativo ). - ME-ID Reivindicações de Função de Administrador (
directoryRole). - Exemplo de declarações de dados do perfil de usuário para o número de telefone celular (
mobilePhone) e a localização do escritório do usuário (officeLocation). - ME-ID Reivindicações de grupo (
directoryGroup). - Um ILogger (
logger) para conveniência no caso de você desejar registrar informações ou erros.
CustomAccountFactory.cs:
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()
: AccountClaimsPrincipalFactory<CustomUserAccount>
{
private readonly ILogger<CustomAccountFactory> logger;
private readonly IServiceProvider serviceProvider;
private readonly string? baseUrl =
string.Join("/",
config.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
config.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider,
ILogger<CustomAccountFactory> logger)
: base(accessor)
{
this.serviceProvider = serviceProvider;
this.logger = logger;
}
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 graphGroups = await requestMemberOf.GraphGroup.GetAsync();
if (graphGroups?.Value is not null)
{
foreach (var entry in graphGroups.Value)
{
if (entry.Id is not null)
{
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()
: AccountClaimsPrincipalFactory<CustomUserAccount>(accessor)
{
private readonly ILogger<CustomAccountFactory> logger;
private readonly IServiceProvider serviceProvider;
public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
IServiceProvider serviceProvider,
ILogger<CustomAccountFactory> logger)
: base(accessor)
{
this.serviceProvider = serviceProvider;
this.logger = logger;
}
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 MemberOf propriedade (IUserMemberOfCollectionWithReferencesRequestBuilder) por TransitiveMemberOf (IUserTransitiveMemberOfCollectionWithReferencesRequestBuilder).
O código anterior ignora as declarações de associação de grupo (groups) que são ME-ID Funções de Administrador (#microsoft.graph.directoryRole tipo) porque os valores GUID retornados por ME-ID são IDs de entidade de Função de Administrador e não IDs de Modelo de Função. Os IDs de entidade não são estáveis entre locatários e não devem ser usados para criar políticas de autorização para usuários em aplicativos. Use sempre IDs de modelo para ME-ID funções de administrador fornecidas por wids declarações.
A reivindicação wids (e, portanto, a reivindicação directoryRole) com um valor de b79fbf4d-3ef9-4689-8143-76b194e85509 existe para contas não de convidados do inquilino. Ele não se refere ao ID de modelo de função de administrador ME-ID.
No aplicativo CLIENT, configure a autenticação de MSAL para usar a fábrica personalizada de contas de utilizador.
Confirme se o Program arquivo usa o Microsoft.AspNetCore.Components.WebAssembly.Authentication namespace:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
Atualize a chamada AddMsalAuthentication para o seguinte. Observe que a Blazor estrutura é RemoteUserAccount substituída pela do aplicativo para a fábrica principal de autenticação MSAL e declarações de CustomUserAccount conta:
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 a API do Graph com ASP.NET Core Blazor WebAssembly e se a wwwroot/appsettings.json configuração está correta de acordo com as diretrizes do SDK do Graph :
var baseUrl =
string.Join("/",
builder.Configuration.GetSection("MicrosoftGraph")["BaseUrl"] ??
"https://graph.microsoft.com",
builder.Configuration.GetSection("MicrosoftGraph")["Version"] ??
"v1.0");
var scopes = builder.Configuration.GetSection("MicrosoftGraph:Scopes")
.Get<List<string>>() ?? [ "user.read" ];
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, ME-ID Função de Administrador ou grupo de segurança no Program arquivo. O exemplo a seguir cria uma política para a função interna 'Administrador de Cobrança' 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, consulte IDs de modelo de função na documentação do Entra. Para obter mais informações sobre políticas de autorização, consulte Autorização baseada em políticas no ASP.NET Core.
Nos exemplos a seguir, o aplicativo CLIENT usa a política anterior para autorizar o usuário.
O AuthorizeView componente 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 [Authorize] diretiva de atributo (AuthorizeAttribute):
@page "/"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "BillingAdministrator")]
Se o utilizador não estiver autorizado, será redirecionado para a página de início de sessão ME-ID.
Uma verificação de política também pode ser realizada em código com lógica processual.
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.";
}
}
}
Usando as abordagens anteriores, você também pode criar acesso baseado em política para funções de aplicativo, onde o GUID usado para a política é definido no appRoles elemento do manifesto do aplicativo no portal do Azure, e grupos de segurança, onde o GUID usado para a política corresponde à ID do objeto do grupo no painel Grupos do portal do Azure.
Autorizar o acesso à API do servidor/API da Web
Um aplicativo de API de servidor pode autorizar os usuários a acessar endpoints de API seguros com políticas de autorização para grupos de segurança, ME-ID Funções de Administrador e Funções de Aplicativo quando um token de acesso contém groups, wids e role claims. O exemplo a seguir cria uma política para a função de Administrador de Cobrança do ME-ID no arquivo Program usando as declarações wids (IDs bem 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 ME-ID Funções de Administrador, consulte IDs de modelo de função na documentação do Azure. Para obter mais informações sobre políticas de autorização, consulte Autorização baseada em políticas no ASP.NET Core.
O acesso a um controlador no aplicativo SERVER pode ser baseado no uso de um [Authorize] atributo com o nome da política (documentação da API: AuthorizeAttribute).
O exemplo a seguir limita o acesso aos dados de faturação para os Administradores de Faturação do Azure, com uma política chamada BillingDataController:
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íticas no ASP.NET Core.
Funções de Aplicação
Para configurar o aplicativo no portal do 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 são configurados com duas funções e as funções são atribuídas a um usuário de teste:
AdminDeveloper
Note
Ao desenvolver um aplicativo hospedado Blazor WebAssembly ou um par cliente-servidor de aplicativos autônomos (um aplicativo autônomo Blazor WebAssembly e um aplicativo de API/API Web do servidor ASP.NET Core), a appRoles propriedade manifest 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 do aplicativo cliente e do servidor, as declarações de função não serão estabelecidas para usuários autenticados da API do servidor/API da Web, mesmo que seu token de acesso tenha as entradas corretas nas declarações de função.
Embora não seja possível atribuir funções a grupos sem uma conta Premium do Microsoft Entra ID, você pode atribuir funções a usuários e receber declarações de função para usuários com uma conta padrão do Azure. As orientações nesta seção não exigem uma conta ME-ID Premium.
Ao trabalhar com o diretório padrão, siga as orientações em Adicionar funções de aplicativo ao seu aplicativo e receba-as no token para configurar e atribuir funções. Se você não estiver trabalhando com o diretório padrão, edite o manifesto do aplicativo no portal do Azure para estabelecer as funções do aplicativo manualmente na entrada appRoles do arquivo de manifesto. A seguir está uma entrada de exemplo appRoles que cria Admin e Developer funções. 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": "{ADMIN GUID}",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Admin"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Developers write code.",
"displayName": "Developer",
"id": "{DEVELOPER GUID}",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Developer"
}
],
Para os espaços reservados {ADMIN GUID} e {DEVELOPER GUID} no exemplo anterior, pode gerar GUIDs com um gerador de GUID online (resultado da pesquisa do Google para "gerador de guid").
Para atribuir uma função a um utilizador (ou grupo, se tiver uma conta do Azure de nível Premium):
- Navegue até Aplicativos corporativos na área ME-ID do portal do Azure.
- Selecione a aplicação. Selecione Gerenciar>usuários e grupos na barra lateral.
- Marque a caixa de seleção para uma ou mais contas de usuário.
- No menu acima da lista de usuários, selecione Editar atribuição.
- Para a entrada Selecionar uma função , selecione Nenhuma selecionada.
- Escolha uma função na lista e use o botão Selecionar para selecioná-la.
- 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 secção Conta de usuário personalizada é configurado para agir em uma role afirmação com um valor de matriz JSON. Adicione e registe o CustomAccountFactory na aplicação CLIENT, conforme mostrado na secção Conta de utilizador personalizada. Não há necessidade de fornecer código para remover a declaração original role porque ela é removida automaticamente pela estrutura.
Program No ficheiro de aplicação CLIENT, especifique a declaração nomeada "appRole" como a declaração de função para as verificações de ClaimsPrincipal.IsInRole:
builder.Services.AddMsalAuthentication(options =>
{
...
options.UserOptions.RoleClaim = "appRole";
});
Note
Se preferir usar a directoryRoles reivindicação (ADD Administrator Roles), atribua "directoryRoles" ao RemoteAuthenticationUserOptions.RoleClaim.
Program No arquivo de um aplicativo SERVER, especifique a declaração chamada "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" como a declaração de função para ClaimsPrincipal.IsInRole verificações:
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); });
Note
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 via AuthenticationOptions. Para obter mais informações, consulte Visão geral da autenticação do ASP.NET Core e o anúncio do ASP.NET Core (aspnet/Announcements #490).
Note
Se preferir usar a wids reivindicação (ADD Administrator Roles), 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 a API do Graph com ASP.NET Core Blazor WebAssembly, você verá uma appRole declaração para cada função atribuída a um usuário conectado (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 a(s) declaração(ões) está(ão) presente(s) conforme o esperado. Ao testar com o Graph SDK localmente, recomendamos o uso de uma nova sessão de navegador in-private/incognito para cada teste para evitar que cookies persistentes interfiram nos testes. Para obter mais informações, consulte Proteger um aplicativo autônomo do ASP.NET Core Blazor WebAssembly com o Microsoft Entra ID.
As abordagens de autorização de componentes são funcionais neste momento. Qualquer um dos mecanismos de autorização em componentes do aplicativo CLIENT pode usar a Admin função para autorizar o usuário:
-
<AuthorizeView Roles="Admin"> [Authorize]Diretiva de atributos (AuthorizeAttribute)@attribute [Authorize(Roles = "Admin")]-
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); var user = authState.User; if (user.IsInRole("Admin")) { ... }
Vários testes de função são suportados:
Exija que o utilizador esteja em
Adminou naDeveloperfunção com oAuthorizeViewcomponente:<AuthorizeView Roles="Admin, Developer"> ... </AuthorizeView>Exija que o utilizador esteja em ambos os
AdmineDeveloperpapéis com oAuthorizeViewcomponente:<AuthorizeView Roles="Admin"> <AuthorizeView Roles="Developer" Context="innerContext"> ... </AuthorizeView> </AuthorizeView>Para obter mais informações sobre o
Contextpara o interno AuthorizeView, consulte ASP.NET Core Blazor autenticação e autorização.Exija que o utilizador esteja ou na
AdminfunçãoDevelopercom o[Authorize]atributo:@attribute [Authorize(Roles = "Admin, Developer")]Exija que o usuário esteja nas funções
AdmineDevelopercom o[Authorize]atributo:@attribute [Authorize(Roles = "Admin")] @attribute [Authorize(Roles = "Developer")]Exija que o usuário esteja na
Admincom códigoDeveloperde 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 utilizador esteja em ambas as
AdmineDeveloperfunções com código procedural, alterando o condicional OU (||) para um condicional E (&&) 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 Admin função para autorizar o usuário:
[Authorize]Diretiva de atributos (AuthorizeAttribute)[Authorize(Roles = "Admin")]-
if (User.IsInRole("Admin")) { ... }
Vários testes de função são suportados:
Exija que o utilizador esteja ou na
AdminfunçãoDevelopercom o[Authorize]atributo:[Authorize(Roles = "Admin, Developer")]Exija que o usuário esteja nas funções
AdmineDevelopercom o[Authorize]atributo:[Authorize(Roles = "Admin")] [Authorize(Roles = "Developer")]Exija que o usuário esteja na
Admincom códigoDeveloperde 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 utilizador esteja em ambas as
AdmineDeveloperfunções com código procedural, alterando o condicional OU (||) para um condicional E (&&) no exemplo anterior:if (User.IsInRole("Admin") && User.IsInRole("Developer"))
Como as comparações de cadeia de caracteres .NET diferenciam maiúsculas de minúsculas, os nomes de função correspondentes também diferenciam maiúsculas de minúsculas. Por exemplo, Admin (em maiúsculas A) não é considerado o mesmo papel que admin (em minúsculas a).
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 invólucro, como caixa de camelo, caixa de kebab e caixa de cobra, são permitidos. O uso de espaços em nomes de funções também é incomum, mas permitido. Por exemplo, billing administrator é um formato de nome de cargo incomum em aplicativos .NET, mas válido.
Recursos adicionais
- IDs de modelo de função (documentação do Entra)
-
groupMembershipClaimsatributo (Entra documentação) - Adicionar funções de aplicativo ao seu aplicativo e recebê-las no token (documentação do Entra)
- Funções do aplicativo (documentação do Azure)
- Autorização baseada em declarações no ASP.NET Core
- Autorização baseada em função no ASP.NET Core
- Autenticação e autorização ASP.NET Core Blazor