Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Quando uma identidade é criada para um usuário de aplicativo ao entrar em um aplicativo, o provedor de identidade pode atribuir uma ou mais declarações à identidade do usuário. Uma declaração é um par de valores nome-valor que representa o que o assunto (um usuário, um aplicativo ou serviço, ou um dispositivo/computador) é, e não o que o assunto pode fazer. Uma declaração pode ser avaliada pelo aplicativo para determinar os direitos de acesso a dados e outros recursos protegidos durante o processo de autorização e também pode ser usada para tomar ou expressar decisões de autenticação sobre um assunto. Uma identidade pode conter várias declarações com vários valores e pode conter várias declarações do mesmo tipo. Este artigo explica como adicionar verificações de declarações para autorização em um aplicativo ASP.NET Core.
Este artigo usa exemplos Razor de componente e se concentra em Blazor cenários de autorização. Para obter diretrizes adicionais Blazor , consulte a seção Recursos adicionais . Para obter diretrizes sobre Razor Pages e MVC, consulte os seguintes recursos:
- Autorização baseada em reivindicação nas Páginas do ASP.NET Core
- autorização baseada em declarações no ASP.NET Core MVC
Aplicativo de exemplo
O exemplo Blazor Web App deste artigo é o aplicativo de exemplo BlazorWebAppAuthorization (repositório GitHub dotnet/AspNetCore.Docs.Samples) (como baixar). O aplicativo de exemplo usa contas semeadas com declarações pré-configuradas para demonstrar a maioria dos exemplos neste artigo. Para obter mais informações, consulte o arquivo README do exemplo (README.md).
Cuidado
Este aplicativo de exemplo usa um banco de dados na memória para armazenar informações do usuário, o que não é adequado para cenários de produção. O aplicativo de exemplo destina-se apenas a fins de demonstração e não deve ser usado como ponto de partida para aplicativos de produção.
Adicionar verificações de declaração
Verificações de autorização baseadas em declaração:
- São declarativas e especificam declarações por meio de políticas que o usuário atual deve apresentar para acessar o recurso solicitado.
- São aplicados a Razor componentes (exemplos neste artigo), Razor páginas ou controladores MVC ou ações dentro de um controlador.
O AuthorizeView componente (AuthorizeView componente na Blazor documentação) dá suporte à autorização baseada em política, em que a política requer uma ou mais declarações de direitos. Como alternativa, uma autorização baseada em declarações por meio de uma ou mais verificações de política pode ser configurada usando [Authorize] atributos em Razor componentes. O desenvolvedor deve criar e registrar uma política expressando os requisitos de declarações. Esta seção aborda conceitos básicos. Para obter cobertura completa, consulte ASP.NET Core Blazor autenticação e autorização.
O tipo mais simples de política de reivindicação procura a presença de uma reivindicação e não verifica o valor.
O registro da política ocorre como parte da configuração do serviço de autorização no arquivo do Program aplicativo:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
Observação
WebApplicationBuilder.ConfigureApplication (reference source) adiciona automaticamente uma chamada para UseAuthorization quando IAuthorizationHandlerProvider é registrado, o que tem sido o comportamento do ASP.NET Core desde o lançamento do .NET 8. Portanto, chamar UseAuthorization explicitamente para aplicativos Blazor do lado do servidor no .NET 8 ou posterior é tecnicamente redundante, mas a chamada não é prejudicial. Chamando-o no código do desenvolvedor depois que ele já tiver sido chamado pela estrutura não tem efeito.
Observação
Links de documentação para .NET fonte de referência geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
O registro da política ocorre como parte da configuração do serviço de autorização no arquivo do Program aplicativo:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
Em aplicativos Blazor Server, chame UseAuthorization após a linha que chama UseAuthentication (se estiver presente):
app.UseAuthentication(); // Only present if not called internally
app.UseAuthorization();
O registro da política ocorre como parte da configuração do serviço de autorização em Startup.ConfigureServices (Startup.cs):
services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeOnly", policy =>
policy.RequireClaim("EmployeeNumber"));
});
Em Blazor Server aplicativos, chame UseAuthorization em Startup.Configure após a linha que chama UseAuthentication (se presente):
app.UseAuthentication(); // Only present if not called internally
app.UseAuthorization();
Blazor WebAssembly aplicativos chamam AddAuthorizationCore no arquivo Program para adicionar serviços de autorização:
builder.Services.AddAuthorizationCore();
Aplique a política usando a Policy propriedade no [Authorize] atributo para especificar o nome da política. No exemplo a seguir, a EmployeeOnly política verifica a presença de uma declaração EmployeeNumber na identidade atual:
Para autorização baseada em política com um componente AuthorizeView, use o parâmetro AuthorizeView.Policy com um único nome de política.
Pages/PassEmployeeOnlyPolicyWithAuthorizeView.razor:
@page "/pass-employeeonly-policy-with-authorizeview"
<h1>Pass 'EmployeeOnly' policy with AuthorizeView</h1>
<AuthorizeView Policy="EmployeeOnly">
<Authorized>
<p>You satisfy the 'EmployeeOnly' policy.</p>
</Authorized>
<NotAuthorized>
<p>You <b>don't</b> satisfy the 'EmployeeOnly' policy.</p>
</NotAuthorized>
</AuthorizeView>
Como alternativa, aplique a política usando a Policy propriedade no [Authorize] atributo para especificar o nome da política. No exemplo a seguir, a EmployeeOnly política verifica a presença de uma declaração EmployeeNumber na identidade atual:
Pages/PassEmployeeOnlyPolicyWithAuthorizeAttribute.razor:
@page "/pass-employeeonly-policy-with-authorize-attribute"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EmployeeOnly")]
<h1>Pass 'EmployeeOnly' policy with [Authorize] attribute</h1>
<p>You satisfy the 'EmployeeOnly' policy.</p>
Você pode especificar uma lista de valores permitidos ao criar uma política. A política a seguir só passa para funcionários cujo número de funcionário seja 1, 2, 3, 4 ou 5:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthorizationBuilder()
.AddPolicy("Founders", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("Founders", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
services.AddAuthorization(options =>
{
options.AddPolicy("Founder", policy =>
policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
});
Pages/PassFounderPolicyWithAuthorizeView.razor:
@page "/pass-founder-policy-with-authorizeview"
<h1>Pass 'Founder' policy with AuthorizeView</h1>
<AuthorizeView Policy="Founder">
<Authorized>
<p>You satisfy the 'Founder' policy.</p>
</Authorized>
<NotAuthorized>
<p>You <b>don't</b> satisfy the 'Founder' policy.</p>
</NotAuthorized>
</AuthorizeView>
Adicionar uma verificação de declaração genérica
Se o valor da declaração não for um único valor ou você precisar de uma lógica de avaliação de declaração mais flexível, como correspondência de padrões, verificação do emissor da declaração ou análise de valores de declaração complexos, use RequireAssertion com HasClaim. Por exemplo, a política a seguir exige que a declaração do email usuário termine com um domínio específico:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
});
services.AddAuthorization(options =>
{
options.AddPolicy("ContosoOnly", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "email" &&
c.Value.EndsWith("@contoso.com", StringComparison.OrdinalIgnoreCase))));
});
Para obter mais informações, consulte Autorização baseada emPolicy em ASP.NET Core.
Avaliar várias políticas
Várias políticas são aplicadas por meio de vários AuthorizeView componentes. O componente interno exige que o usuário passe sua política e todas as políticas dos componentes pai AuthorizeView.
O exemplo a seguir:
- Requer uma
CustomerServiceMemberdiretriz, que indica que o usuário está no departamento de atendimento ao cliente da organização, dado que possui umaDepartmentreivindicação com um valor deCustomer Service. - Também requer uma política
HumanResourcesMember, que indica que o usuário está no departamento de recursos humanos da organização porque possui uma declaraçãoDepartmentcom um valor deHuman Resources.
No arquivo Program do aplicativo:
builder.Services.AddAuthorizationBuilder()
.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"))
.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
No arquivo Program do aplicativo:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"));
options.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
});
Em Startup.ConfigureServices (Startup.cs):
services.AddAuthorization(options =>
{
options.AddPolicy("CustomerServiceMember", policy =>
policy.RequireClaim("Department", "Customer Service"));
options.AddPolicy("HumanResourcesMember", policy =>
policy.RequireClaim("Department", "Human Resources"));
});
O exemplo a seguir usa AuthorizeView componentes.
Pages/PassCustomerServiceMemberAndHumanResourcesMemberPoliciesWithAuthorizeViews.razor:
@page "/pass-customerservicemember-and-humanresourcesmember-policies-with-authorizeviews"
<h1>Pass 'CustomerServiceMember' and 'HumanResourcesMember' policies with AuthorizeViews</h1>
<AuthorizeView Policy="CustomerServiceMember">
<Authorized>
<p>User: @context.User.Identity?.Name</p>
<AuthorizeView Policy="HumanResourcesMember" Context="innerContext">
<Authorized>
<p>
You satisfy the 'CustomerServiceMember' and 'HumanResourcesMember' policies.
</p>
</Authorized>
<NotAuthorized>
<p>
You satisfy the 'CustomerServiceMember' policy, but you <b>don't</b> satisfy
the 'HumanResourcesMember' policy.
</p>
</NotAuthorized>
</AuthorizeView>
</Authorized>
<NotAuthorized>
<p>
You <b>don't</b> satisfy the 'CustomerServiceMember' policy.
</p>
</NotAuthorized>
</AuthorizeView>
O exemplo a seguir usa atributos[Authorize].
Pages/PassCustomerServiceMemberAndHumanResourcesMemberPoliciesWithAuthorizeAttributes.razor:
@page "/pass-customerservicemember-and-humanresourcesmember-policies-with-authorize-attributes"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "CustomerServiceMember")]
@attribute [Authorize(Policy = "HumanResourcesMember")]
<h1>
Pass 'CustomerServiceMember' and 'HumanResourcesMember' policies with [Authorize] attributes
</h1>
<p>
You satisfy the 'CustomerServiceMember' and 'HumanResourcesMember' policies.
</p>
Para políticas mais complicadas, como interpretar uma declaração de data de nascimento, calcular uma idade a partir dela e verificar se a idade é 21 anos ou mais, utilize RequireAssertion ou escreva manipuladores de política personalizados. Manipuladores de política personalizados são úteis quando você precisa de acesso a serviços injetados por dependência ou deseja um componente de autorização reutilizável e testável.
Sensibilidade a maiúsculas e minúsculas
Os valores de reivindicação são comparados usando StringComparison.Ordinal. Isso significa que Admin (maiúscula A) e admin (minúscula a) são sempre considerados papéis diferentes, independentemente de qual manipulador de autenticação criou a identidade.
Separadamente, a comparação de tipo de reivindicação (usada para localizar declarações de função por seu tipo de reivindicação, como http://schemas.microsoft.com/ws/2008/06/identity/claims/role) pode diferenciar entre sensível ou insensível a maiúsculas, dependendo da ClaimsIdentity implementação. Com Microsoft.IdentityModel em ASP.NET Core 8.0 ou posterior (usado por AddJwtBearer, AddOpenIdConnect, AddWsFederation e AddMicrosoftIdentityWebApp/AddMicrosoftIdentityWebApi), CaseSensitiveClaimsIdentity é produzido durante a validação de tokens, que usa correspondência exata de tipos de declaração sensível a maiúsculas e minúsculas.
O ClaimsIdentity padrão fornecido pelo .NET runtime (usado na maioria dos casos, incluindo todos os fluxos baseados em cookie) ainda utiliza a correspondência de tipos de declaração que não diferencia maiúsculas de minúsculas.
Na prática, essa distinção raramente importa para autorização de função porque o tipo de declaração de função é definido uma vez durante a criação de identidade e correspondido consistentemente. Sempre use maiúsculas e minúsculas consistentes para nomes de funções e tipos de reivindicação para evitar problemas sutis.
Recursos adicionais
- ASP.NET Core Blazor autenticação e autorização
- ASP.NET Core Blazor estado de autenticação
- ASP.NET Core Blazor WebAssembly cenários de segurança adicionais
- Use API do Graph com ASP.NET Core Blazor WebAssembly
- Secure ASP.NET Core Blazor WebAssembly
- Autorização baseada em reivindicação nas Páginas do ASP.NET Core
- autorização baseada em declarações no ASP.NET Core MVC
-
Estender ou adicionar declarações personalizadas, incluindo declarações de função, usando
IClaimsTransformation