Autenticação e autorização do Blazor no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 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 a versão atual, consulte a versão .NET 9 deste artigo.
Este artigo descreve o suporte do ASP.NET Core para a configuração e o gerenciamento de segurança em aplicativos Blazor.
Os cenários de segurança diferem entre o código de autorização executado no lado do servidor e no lado do cliente em aplicativos Blazor. Para o código de autorização executado no servidor, as verificações de autorização são capazes de impor regras de acesso para áreas do aplicativo e componentes. Como a execução do código do lado do cliente pode ser adulterada, não se pode confiar no código de autorização em execução no cliente para impor regras de acesso ou controlar a exibição do conteúdo do lado do cliente.
Se a aplicação da regra de autorização tiver de ser garantida, não implemente verificações de autorização no código do lado do cliente. Crie um Blazor Web App que dependa apenas da SSR (renderização do lado do servidor) para verificações de autorização e aplicação de regras.
Se a aplicação das regras de autorização e a segurança dos dados e do código precisarem ser garantidas, não desenvolva um aplicativo do lado do cliente. Crie um aplicativo Blazor Server.
As convenções de autorização do Razor Pages não se aplicam a componentes Razor roteáveis. Se um componente Razor não roteável for inserido em uma página de um aplicativo do Razor Pages, as convenções de autorização da página afetarão indiretamente o componente Razor junto com o rest do conteúdo da página.
O ASP.NET Core Identity foi projetado para funcionar no contexto da comunicação de solicitação e resposta HTTP, que geralmente não é o modelo de comunicação cliente-servidor do aplicativo Blazor. Os aplicativos ASP.NET Core que usam o ASP.NET Core Identity para gerenciamento de usuários devem usar Razor Pages em vez de componentes Razor para interface do usuário relacionada a Identity, como registro de usuário, logon, logoff e outras tarefas de gerenciamento de usuários. A criação de componentes Razor que lidam diretamente com tarefas Identity é possível para vários cenários, mas não é recomendada ou compatível com a Microsoft.
Abstrações do ASP.NET Core, como SignInManager<TUser> eUserManager<TUser>, não têm suporte em componentes Razor. Para obter mais informações sobre como usar o ASP.NET Core Identity com Blazor, confira Scaffold ASP.NET CoreIdentity em um aplicativo Blazor do lado do servidor.
Observação
Os exemplos de código neste artigo adotam NRTs (tipos de referência anuláveis) e análise estática de estado nulo do compilador do .NET, que têm suporte no ASP.NET Core no .NET 6 ou posterior. Ao usar o ASP.NET Core 5.0 ou anterior, remova a designação de tipo nulo (?
) dos exemplos neste artigo.
Mantenha dados e credenciais confidenciais com segurança
Não armazene segredos de aplicativo, cadeias de conexão, credenciais, senhas, PINs (números de identificação pessoal), código .NET/C# privado ou chaves/tokens privados no código do lado do cliente, que é sempre inseguro. O código do lado Blazor do cliente deve acessar serviços e bancos de dados seguros por meio de uma API Web segura que você controla.
Em ambientes de teste/preparo e produção, o código do lado do Blazor servidor e as APIs Web devem usar fluxos de autenticação seguros que evitam a manutenção de credenciais no código do projeto ou nos arquivos de configuração. Fora dos testes de desenvolvimento local, recomendamos evitar o uso de variáveis de ambiente para armazenar dados confidenciais, pois as variáveis de ambiente não são a abordagem mais segura. Para testes de desenvolvimento local, a ferramenta Gerenciador de segredos é recomendada para proteger dados confidenciais. Para saber mais, consulte os recursos a seguir:
- Fluxos de autenticação seguros (documentação principal do ASP.NET)
- Identidades gerenciadas para serviços do Microsoft Azure (este artigo)
Para desenvolvimento e teste local do lado do cliente e do lado do servidor, use a ferramenta Secret Manager para proteger credenciais confidenciais.
Identidades gerenciadas para serviços do Microsoft Azure
Para serviços do Microsoft Azure, recomendamos o uso de identidades gerenciadas. As identidades gerenciadas autenticam de maneira segura para serviços do Azure sem armazenar credenciais no código do aplicativo. Para saber mais, consulte os recursos a seguir:
- O que são identidades gerenciadas para recursos do Azure? (Documentação do Microsoft Entra)
- Documentação dos serviços do Azure
Suporte à anti-falsificação
O modelo Blazor:
- Adiciona serviços antifalsificação automaticamente quando AddRazorComponents é chamado no arquivo
Program
. - Adiciona middleware antifalsificação chamando UseAntiforgery em seu pipeline de processamento de solicitação no arquivo
Program
e requer proteção antifalsificação do ponto de extremidade para mitigar as ameaças de CSRF/XSRF (solicitação intersite forjada). UseAntiforgery é chamado após UseHttpsRedirection. Uma chamada para UseAntiforgery deve ser feita após chamadas, se houver, para UseAuthentication e UseAuthorization.
O componente AntiforgeryToken renderiza um token antifalsificação como um campo oculto, e esse componente é adicionado automaticamente às instâncias (EditForm) do formulário. Para obter mais informações, consulte ASP.NET CoreBlazor Visão geral dos formulários.
O serviço AntiforgeryStateProvider fornece acesso a um token antifalsificação associado à sessão atual. Injete o serviço e chame seu método GetAntiforgeryToken() para obter o AntiforgeryRequestToken atual. Para obter mais informações, consulte Chame uma API Web de um Blazoraplicativo ASP.NET Core.
Blazor armazena tokens de solicitação no estado do componente, o que garante que os tokens antifalsificação estejam disponíveis para os componentes interativos, mesmo quando eles não têm acesso à solicitação.
Observação
A mitigação antifalsificação só é necessária ao enviar dados de formulário para o servidor codificado como application/x-www-form-urlencoded
, multipart/form-data
ou text/plain
, pois esses são os únicos tipos de formulário válidos.
Para saber mais, consulte os recursos a seguir:
- Prevenir ataques de XSRF/CSRF (solicitação intersite forjada) no ASP.NET Core: esse artigo é o principal artigo do ASP.NET Core sobre o assunto, que se aplica ao Blazor Server do lado do servidor, ao projeto de servidor dos Blazor Web Apps e à integração do Blazor às Páginas MVC/Razor.
- Blazor Visão geral de formulários do ASP.NET Core: A seção suporte antifalsificação do artigo refere-se ao Blazor suporte antifalsificação de formulários.
Autenticação
O Blazor usa os mecanismos de autenticação do ASP.NET Core para estabelecer a identity do usuário. O mecanismo exato depende de como o aplicativo Blazor está hospedado, no servidor ou do lado do cliente.
Autenticação de Blazor do lado do servidor
O lado do servidor renderizado interativamente Blazor opera em uma conexão SignalR com o cliente. A autenticação em aplicativos baseados em SignalR é realizada quando a conexão é estabelecida. A autenticação pode ser baseada em um cookie ou em outro token de portador, mas a autenticação é gerenciada por meio do hub SignalR e totalmente dentro do circuito.
O serviço AuthenticationStateProvider interno ou personalizado obtém dados de estado de autenticação do HttpContext.User do ASP.NET Core. Essa é a maneira que o estado de autenticação se integra a mecanismos de autenticação existentes do ASP.NET Core.
Para mais informações sobre autenticação do lado do servidor, consulte Aplicativos Blazor seguros do lado do servidor do ASP.NET Core
IHttpContextAccessor
/HttpContext
em Razor componentes
IHttpContextAccessor deve ser evitado com a renderização interativa porque não há um HttpContext
disponível válido.
IHttpContextAccessor pode ser usado para componentes que são renderizados estaticamente no servidor. No entanto, recomendamos evitá-lo, se possível.
HttpContext pode ser usado como um parâmetro em cascata apenas em componentes raiz renderizados estaticamente para tarefas gerais, como inspecionar e modificar cabeçalhos ou outras propriedades no componente App
(Components/App.razor
). O valor é sempre null
para renderização interativa.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Para cenários em que o componente HttpContext é necessário em componentes interativos, recomendamos fluir os dados por meio do estado de componente persistente do servidor. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Não use IHttpContextAccessor/HttpContext direta ou indiretamente nos componentes Razor dos aplicativos Blazor do lado do servidor. Os aplicativos Blazor são executados fora do contexto do pipeline ASP.NET Core. Não há garantia de que o HttpContext esteja disponível no IHttpContextAccessor e não há garantia de que o HttpContext mantenha o contexto que iniciou o aplicativo Blazor.
A abordagem recomendada para passar o estado da solicitação para o aplicativo Blazor é por meio de parâmetros de componente raiz durante a renderização inicial do aplicativo. Como alternativa, o aplicativo pode copiar os dados para um serviço com escopo no evento de ciclo de vida de inicialização do componente raiz para uso em todo o aplicativo. Para obter mais informações, confira Cenários de segurança adicionais Blazor do ASP.NET Core do lado do servidor.
Um aspecto crítico da segurança do lado Blazor do servidor é que o usuário conectado a um determinado circuito pode ser atualizado em algum momento após Blazoro circuito do SignalR ser estabelecido, mas o IHttpContextAccessornão é atualizado. Para obter mais informações sobre como lidar com essa situação usando serviços personalizados, confira Outros cenários de segurança do ASP.NET Core Blazor do lado do servidor.
Estado compartilhado
Os aplicativos Blazor do lado do servidor estão localizados na memória do servidor, e várias sessões de aplicativo são hospedadas no mesmo processo. Para cada sessão de aplicativo, Blazor inicia um circuito com seu próprio escopo de contêiner de injeção de dependência. Portanto, os serviços com escopo são exclusivos por sessão Blazor.
Aviso
Não recomendamos que os aplicativos no mesmo estado de compartilhamento de servidor usem serviços singleton, a menos que sejam tomados cuidados extremos, pois isso pode introduzir vulnerabilidades de segurança, como o vazamento do estado do usuário entre circuitos.
Você pode usar serviços singleton com estado em aplicativos Blazor, se forem criados especificamente para isso. Por exemplo, o uso de um cache de memória singleton é aceitável porque um cache de memória requer uma chave para acessar determinada entrada. Supondo que os usuários não tenham controle sobre as chaves de cache usadas com o cache, o estado armazenado no cache não vazará entre circuitos.
Para obter diretrizes gerais sobre o gerenciamento de estado, confira Gerenciamento de estado Blazor do ASP.NET Core.
Autenticação de Blazor do lado do cliente
Em aplicativos do lado do cliente Blazor, as verificações de autenticação do lado do cliente podem ser ignoradas porque todo o código do lado do cliente pode ser modificado pelos usuários. Isso também ocorre com todas as tecnologias de aplicativo do lado do cliente, incluindo estruturas de SPA do JavaScript e aplicativos nativos em qualquer sistema operacional.
Adicione o seguinte:
Uma referência de pacote para o pacote NuGet
Microsoft.AspNetCore.Components.Authorization
.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.
O namespace Microsoft.AspNetCore.Components.Authorization para o arquivo do aplicativo
_Imports.razor
.
Para lidar com a autenticação, use um serviço AuthenticationStateProvider interno ou personalizado.
Para mais informações sobre autenticação do lado do cliente, consulte ASP.NET Core Blazor WebAssembly seguro.
Serviço AuthenticationStateProvider
O AuthenticationStateProvider é o serviço subjacente usado pelo componente AuthorizeView e pelos serviços de autenticação em cascata para obter o estado de autenticação de um usuário.
O AuthenticationStateProvider é o serviço subjacente usado pelos componentes AuthorizeView e CascadingAuthenticationState para obter o estado de autenticação para um usuário.
Normalmente, você não usa o AuthenticationStateProvider diretamente. Use as abordagens do componente AuthorizeView
ou Task<AuthenticationState>
descritas mais adiante neste artigo. A principal desvantagem de usar o AuthenticationStateProvider diretamente é que o componente não será notificado automaticamente se os dados subjacentes do estado de autenticação forem alterados.
Para implementar um AuthenticationStateProvider personalizado, consulte Estado de autenticação do ASP.NET Core Blazor, que inclui diretrizes sobre como implementar notificações de alteração de estado de autenticação do usuário.
Obter os dados principais de declarações de um usuário
O serviço AuthenticationStateProvider pode fornecer os dados de ClaimsPrincipal do usuário atual, conforme mostrado no exemplo a seguir.
ClaimsPrincipalData.razor
:
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>ClaimsPrincipal Data</h1>
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
<p>@authMessage</p>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
<p>@surname</p>
@code {
private string? authMessage;
private string? surname;
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
private async Task GetClaimsPrincipalData()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
claims = user.Claims;
surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
}
else
{
authMessage = "The user is NOT authenticated.";
}
}
}
No exemplo anterior:
- ClaimsPrincipal.Claims retorna as declarações do usuário (
claims
) para exibição na interface do usuário. - A linha que obtém o sobrenome do usuário (
surname
) chama ClaimsPrincipal.FindAll com um predicado para filtrar as declarações do usuário.
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>ClaimsPrincipal Data</h1>
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
<p>@authMessage</p>
@if (claims.Any())
{
<ul>
@foreach (var claim in claims)
{
<li>@claim.Type: @claim.Value</li>
}
</ul>
}
<p>@surname</p>
@code {
private string? authMessage;
private string? surname;
private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();
private async Task GetClaimsPrincipalData()
{
var authState = await AuthenticationStateProvider
.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
claims = user.Claims;
surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
}
else
{
authMessage = "The user is NOT authenticated.";
}
}
}
Se user.Identity.IsAuthenticated
for true
e como o usuário é um ClaimsPrincipal, será possível enumerar as declarações e avaliar a associação nas funções.
Para obter mais informações sobre DI (injeção de dependência) e serviços, consulte Injeção de dependência de Blazor do ASP.NET Core e Injeção de dependência no ASP.NET Core. Para informações sobre como implementar um AuthenticationStateProvider personalizado, consulte Estado de autenticação do ASP.NET Core Blazor.
Expor o estado de autenticação como um parâmetro em cascata
Se os dados do estado de autenticação forem necessários para a lógica do procedimento, como ao realizar uma ação disparada pelo usuário, obtenha os dados de estado de autenticação definindo um parâmetro em cascata do tipo Task<
AuthenticationState>
, conforme demonstrado no exemplo a seguir.
CascadeAuthState.razor
:
@page "/cascade-auth-state"
<h1>Cascade Auth State</h1>
<p>@authMessage</p>
@code {
private string authMessage = "The user is NOT authenticated.";
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
protected override async Task OnInitializedAsync()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user?.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
}
}
}
}
@page "/cascade-auth-state"
<h1>Cascade Auth State</h1>
<p>@authMessage</p>
@code {
private string authMessage = "The user is NOT authenticated.";
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
protected override async Task OnInitializedAsync()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user?.Identity is not null && user.Identity.IsAuthenticated)
{
authMessage = $"{user.Identity.Name} is authenticated.";
}
}
}
}
Se user.Identity.IsAuthenticated
for true
, será possível enumerar as declarações e avaliar a associação nas funções.
Configurar o Task<
AuthenticationState>
parâmetro em cascata usando os serviços de AuthorizeRouteView e autenticação em cascata.
Ao criar um aplicativo Blazor a partir de um dos modelos de projeto Blazor com a autenticação habilitada, o aplicativo inclui o AuthorizeRouteView e a chamada para AddCascadingAuthenticationState mostrados no exemplo a seguir. Um aplicativo Blazor do lado do cliente também inclui os registros de serviço necessários. Informações adicionais são apresentadas na seção Personalizar conteúdo não autorizado com o componente Router
.
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)" />
...
</Found>
</Router>
No arquivo Program
, registre os serviços de estado de autenticação em cascata:
builder.Services.AddCascadingAuthenticationState();
Configurar o Task<
AuthenticationState>
parâmetro em cascata usando os componentes AuthorizeRouteView e CascadingAuthenticationState.
Ao criar um aplicativo Blazor a partir de um dos modelos de projeto Blazor com a autenticação habilitada, o aplicativo inclui os componentes AuthorizeRouteView e CascadingAuthenticationState mostrados no exemplo a seguir. Um aplicativo Blazor do lado do cliente também inclui os registros de serviço necessários. Informações adicionais são apresentadas na seção Personalizar conteúdo não autorizado com o componente Router
.
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
...
</Found>
</Router>
</CascadingAuthenticationState>
Observação
Com a versão do ASP.NET Core 5.0.1 e para qualquer lançamento adicional do 5.x, o componente Router
inclui o parâmetro PreferExactMatches
definido como @true
. Para obter mais informações, consulte Migrar do ASP.NET Core 3.1 para o 5.0.
Em um aplicativo Blazor do cliente, adicione serviços de autorização ao arquivo Program
:
builder.Services.AddAuthorizationCore();
Em um aplicativo Blazor do cliente, adicione opções e serviços de autorização ao arquivo Program
:
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
Em um aplicativo Blazor do lado do servidor, os serviços de opções e autorização já estão presentes, portanto, nenhuma etapa adicional é necessária.
Autorização
Depois que o usuário é autenticado, as regras de autorização são aplicadas para controlar o que ele poderá fazer.
O acesso geralmente é concedido ou negado com base nos seguintes casos:
- Se o usuário está autenticado (conectado).
- Se o usuário está em uma função.
- Se o usuário tem uma declaração.
- Se uma política é atendida.
Todos esses conceitos são iguais no MVC do ASP.NET Core ou em aplicativos Razor Pages. Para obter mais informações sobre a segurança do ASP.NET Core, confira os artigos em Segurança e Identity do ASP.NET Core.
componente AuthorizeView
O componente AuthorizeView exibe de modo seletivo o conteúdo da interface do usuário, caso o usuário esteja autorizado. Essa abordagem é útil quando você precisa apenas exibir dados para o usuário e não precisa usar a identity dele na lógica de procedimento.
O componente expõe uma variável context
do tipo AuthenticationState (@context
na sintaxe Razor), que pode ser usada para acessar informações sobre o usuário conectado:
<AuthorizeView>
<p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>
Você também pode fornecer conteúdo diferente para exibição se o usuário não estiver autorizado com uma combinação dos parâmetros Authorized e NotAuthorized:
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
<p><button @onclick="HandleClick">Authorized Only Button</button></p>
</Authorized>
<NotAuthorized>
<p>You're not authorized.</p>
</NotAuthorized>
</AuthorizeView>
@code {
private void HandleClick() { ... }
}
Embora o AuthorizeView componente controle a visibilidade dos elementos com base no status de autorização do usuário, ele não impõe segurança no próprio manipulador de eventos. No exemplo anterior, o HandleClick
método é associado apenas a um botão visível para usuários autorizados, mas nada impede a invocação desse método de outros lugares. Para garantir a segurança no nível do método, implemente a lógica de autorização adicional no próprio manipulador ou na API relevante.
Os componentes Razor de Blazor Web Apps nunca exibem o conteúdo <NotAuthorized>
quando a autorização falha no lado do servidor durante a SSR estática (renderização estática do lado do servidor). O pipeline do ASP.NET Core no lado do servidor processa a autorização no servidor. Use técnicas do lado do servidor para lidar com solicitações não autorizadas. Para obter mais informações, consulte ASP.NET Core Blazor modos de renderização.
Aviso
A marcação do lado do cliente e os métodos associados a um AuthorizeView são protegidos apenas contra exibição e execução na interface do usuário renderizada em aplicativos Blazor do lado do cliente. Para proteger o conteúdo autorizado e os métodos seguros no Blazor do lado do cliente, o conteúdo geralmente é fornecido por uma chamada segura e autorizada da API Web para uma API do lado do servidor e nunca é armazenado no aplicativo. Para obter mais informações, consulte Chamar uma API Web de um aplicativo ASP.NET Core Blazor e Cenários de segurança adicionais do ASP.NET Core Blazor WebAssembly.
O conteúdo de Authorized e NotAuthorized pode incluir itens arbitrários, como outros componentes interativos.
As condições de autorização, como funções ou políticas que controlam o acesso ou as opções da interface do usuário, são abordadas na seção Autorização.
Se as condições de autorização não forem especificadas, o AuthorizeView usará uma política padrão:
- Usuários autenticados (conectados) estão autorizados.
- Usuários não autenticados (não conectados) não estão autorizados.
O componente AuthorizeView pode ser usado no componente NavMenu
(Shared/NavMenu.razor
) para exibir um componente NavLink
(NavLink), mas observe que essa abordagem remove apenas o item de lista da saída renderizada. Isso não impede que o usuário navegue até o componente. Implemente a autorização separadamente no componente de destino.
Autorização baseada em funções e em políticas
O componente AuthorizeView dá suporte à autorização baseada em funções ou baseada em políticas.
Para a autorização baseada em funções, use o parâmetro Roles. No exemplo a seguir, o usuário deve ter uma declaração de função para as funções Admin
ou Superuser
:
<AuthorizeView Roles="Admin, Superuser">
<p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>
Para exigir que um usuário tenha declarações de função Admin
e Superuser
, aninhe os componentes AuthorizeView:
<AuthorizeView Roles="Admin">
<p>User: @context.User</p>
<p>You have the 'Admin' role claim.</p>
<AuthorizeView Roles="Superuser" Context="innerContext">
<p>User: @innerContext.User</p>
<p>You have both 'Admin' and 'Superuser' role claims.</p>
</AuthorizeView>
</AuthorizeView>
O código anterior estabelece um Context
para o componente interno AuthorizeView para evitar uma colisão de contexto AuthenticationState. O contexto AuthenticationState é acessado no AuthorizeView externo com a abordagem padrão para acessar o contexto (@context.User
). O contexto é acessado no AuthorizeView internos com o contexto nomeado innerContext
(@innerContext.User
).
Para obter mais informações, incluindo diretrizes de configuração, consulte Autorização baseada em função no ASP.NET Core.
Para autorização baseada em política, use o Policy parâmetro com um único nome de política:
<AuthorizeView Policy="Over21">
<p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>
Caso o usuário precise cumprir uma das várias políticas, crie uma política que confirme que o usuário atende a outras políticas.
Caso o usuário precise atender a várias políticas simultaneamente, siga uma das seguintes abordagens:
Crie uma política para AuthorizeView que confirme que o usuário atende a várias outras políticas.
Aninhar as políticas em vários componentes AuthorizeView:
<AuthorizeView Policy="Over21"> <AuthorizeView Policy="LivesInCalifornia"> <p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p> </AuthorizeView> </AuthorizeView>
A autorização baseada em declarações é um caso especial de autorização baseada em políticas. Por exemplo, você pode definir uma política que exige que os usuários tenham determinada declaração. Para obter mais informações, consulte Autorização baseada em política no ASP.NET Core.
Se Roles e Policy não forem especificados, o AuthorizeView usará a política padrão:
- Usuários autenticados (conectados) estão autorizados.
- Usuários não autenticados (não conectados) não estão autorizados.
Como as comparações de cadeia de caracteres do .NET diferenciam maiúsculas de minúsculas por padrão, a correspondência entre nomes de função e de política 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 e política (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 e política é incomum, mas permitido pela estrutura. Por exemplo, billing administrator
é um formato incomum de função ou nome de política em aplicativos .NET, mas é uma função ou nome de política válido.
Conteúdo exibido durante a autenticação assíncrona
O Blazor permite que o estado de autenticação seja determinado de modo assíncrono. O cenário principal dessa abordagem ocorre em aplicativos Blazor do lado do cliente que fazem uma solicitação a um ponto de extremidade externo para autenticação.
Enquanto a autenticação estiver em andamento, AuthorizeView não exibirá nenhum conteúdo. Para exibir o conteúdo durante a autenticação, atribua conteúdo ao parâmetro Authorizing:
<AuthorizeView>
<Authorized>
<p>Hello, @context.User.Identity?.Name!</p>
</Authorized>
<Authorizing>
<p>You can only see this content while authentication is in progress.</p>
</Authorizing>
</AuthorizeView>
Normalmente, essa abordagem não é aplicável a aplicativos Blazor do lado do servidor. Os aplicativos Blazor do lado do servidor ficam conhecendo o estado de autenticação assim que ele é estabelecido. O conteúdo Authorizing pode ser fornecido em um componente AuthorizeView do aplicativo, mas o conteúdo nunca é exibido.
Atributo [Authorize]
O atributo [Authorize]
está disponível em componentes Razor:
@page "/"
@attribute [Authorize]
You can only see this if you're signed in.
Importante
Use [Authorize]
somente em componentes @page
acessados por meio do roteador Blazor. A autorização é realizada apenas como um aspecto do roteamento e não para componentes filho renderizados dentro de uma página. Para autorizar a exibição de partes específicas dentro de uma página, use AuthorizeView.
O atributo [Authorize]
também dá suporte à autorização baseada em funções ou em políticas. Para a autorização baseada em funções, use o parâmetro Roles:
@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]
<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>
Para a autorização baseada em políticas, use o parâmetro Policy:
@page "/"
@attribute [Authorize(Policy = "Over21")]
<p>You can only see this if you satisfy the 'Over21' policy.</p>
Se Roles e Policy não forem especificados, o [Authorize]
usará a política padrão:
- Usuários autenticados (conectados) estão autorizados.
- Usuários não autenticados (não conectados) não estão autorizados.
Quando o usuário não tem autorização o e se o aplicativo não personalizar conteúdo não autorizado com o componente Router
, a estrutura exibirá automaticamente a seguinte mensagem de fallback:
Not authorized.
Autorização de recursos
Para autorizar usuários para recursos, passe os dados de rota da solicitação para o parâmetro Resource de AuthorizeRouteView.
No conteúdo Router.Found de uma rota solicitada:
<AuthorizeRouteView Resource="routeData" RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
Para obter mais informações sobre como os dados de estado de autorização são passados e usados na lógica de procedimento, consulte a seção Expor o estado de autenticação como um parâmetro em cascata.
Quando o AuthorizeRouteView recebe os dados de rota para o recurso, as políticas de autorização têm acesso a RouteData.PageType e RouteData.RouteValues que permite que a lógica personalizada tome decisões de autorização.
No exemplo a seguir, uma política EditUser
é criada em AuthorizationOptions para a configuração do serviço de autorização do aplicativo (AddAuthorizationCore) com a seguinte lógica:
- Determine se existe um valor de rota com uma chave de
id
. Se a chave existir, o valor da rota será armazenado emvalue
. - Em uma variável chamada
id
, armazenevalue
como uma cadeia de caracteres ou defina um valor de cadeia de caracteres vazio (string.Empty
). - Se
id
não for uma cadeia de caracteres vazia, afirme que a política será atendida (retornartrue
) se o valor da cadeia de caracteres começar comEMP
. Caso contrário, declare que a política falhará (retornarfalse
).
No arquivo Program
:
Adicione namespaces para Microsoft.AspNetCore.Components e System.Linq:
using Microsoft.AspNetCore.Components; using System.Linq;
Adicione a política:
options.AddPolicy("EditUser", policy => policy.RequireAssertion(context => { if (context.Resource is RouteData rd) { var routeValue = rd.RouteValues.TryGetValue("id", out var value); var id = Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty; if (!string.IsNullOrEmpty(id)) { return id.StartsWith("EMP", StringComparison.InvariantCulture); } } return false; }) );
O exemplo anterior é uma política de autorização simplificada, usada apenas para demonstrar o conceito com um exemplo em funcionamento. Para obter mais informações sobre como criar e configurar políticas de autorização, consulte Autorização baseada em política no ASP.NET Core.
No componente EditUser
a seguir, o recurso em /users/{id}/edit
tem um parâmetro de rota para o identificador do usuário ({id}
). O componente usa a política de autorização EditUser
anterior para determinar se o valor da rota para id
começa com EMP
. Se id
começar com EMP
, a política terá êxito e o acesso ao componente será autorizado. Se id
começar com um valor diferente EMP
ou se id
for uma cadeia de caracteres vazia, a política falhará e o componente não será carregado.
EditUser.razor
:
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]
<h1>Edit User</h1>
<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>
@code {
[Parameter]
public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]
<h1>Edit User</h1>
<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>
@code {
[Parameter]
public string? Id { get; set; }
}
Personalizar o conteúdo não autorizado com o componente Router
O componente Router, em conjunto com o componente AuthorizeRouteView, permitirá que o aplicativo especifique o conteúdo personalizado se:
- O usuário não atender à condição
[Authorize]
aplicada ao componente. A marcação do elemento<NotAuthorized>
for exibida. O atributo[Authorize]
é abordado na seção Atributo[Authorize]
. - A autorização assíncrona estiver em andamento, o que geralmente significa que o processo de autenticação do usuário está em andamento. A marcação do elemento
<Authorizing>
for exibida.
Importante
Os recursos do roteador Blazor que exibem o conteúdo <NotAuthorized>
e <NotFound>
não estão operacionais durante a renderização estática do lado do servidor (SSR estática) porque o processamento de solicitações é totalmente tratado pelo processamento de solicitações do pipeline de middleware do ASP.NET Core e os componentes Razor não são renderizados para solicitações não autorizadas ou incorretas. Use técnicas do lado do servidor para lidar com solicitações não autorizadas e ruins durante a SSR estática. Para obter mais informações, consulte ASP.NET Core Blazor modos de renderização.
<Router ...>
<Found ...>
<AuthorizeRouteView ...>
<NotAuthorized>
...
</NotAuthorized>
<Authorizing>
...
</Authorizing>
</AuthorizeRouteView>
</Found>
</Router>
O conteúdo de Authorized e NotAuthorized pode incluir itens arbitrários, como outros componentes interativos.
Observação
O mencionado anteriormente requer o registro dos serviços de estado de autenticação em cascata no arquivo Program
do aplicativo:
builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView ...>
<NotAuthorized>
...
</NotAuthorized>
<Authorizing>
...
</Authorizing>
</AuthorizeRouteView>
</Found>
</Router>
</CascadingAuthenticationState>
O conteúdo de NotFound, Authorized e NotAuthorized pode incluir itens arbitrários, como outros componentes interativos.
Se o conteúdo NotAuthorized não for especificado, o AuthorizeRouteView usará a mensagem de fallback a seguir:
Not authorized.
Um aplicativo criado a partir do modelo de projeto Blazor WebAssembly com a autenticação habilitada inclui um componente RedirectToLogin
, que é posicionado no conteúdo <NotAuthorized>
do componente Router. Quando um usuário não é autenticado (context.User.Identity?.IsAuthenticated != true
), o componente RedirectToLogin
redireciona o navegador para o ponto de extremidade authentication/login
para autenticação. O usuário é retornado à URL solicitada após a autenticação com o provedor de identity.
Lógica de procedimento
Se for necessário que o aplicativo verifique as regras de autorização como parte da lógica de procedimento, use um parâmetro em cascata do tipo Task<
AuthenticationState>
para obter o ClaimsPrincipal do usuário. Task<
AuthenticationState>
pode ser combinado com outros serviços, como IAuthorizationService
, para avaliar as políticas.
No exemplo a seguir:
- O
user.Identity.IsAuthenticated
executa o código para usuários autenticados (conectados). - O
user.IsInRole("admin")
executa o código para usuários na função de "Administrador". - O
(await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded
executa o código para usuários que satisfazem a política de "editor de conteúdo".
Um aplicativo Blazor do lado do servidor inclui os namespaces apropriados quando criado a partir do modelo de projeto. Em um aplicativo Blazor do lado do cliente, confirme a presença dos namespaces Microsoft.AspNetCore.Authorization e Microsoft.AspNetCore.Components.Authorization no componente ou no arquivo _Imports.razor
do aplicativo:
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
ProceduralLogic.razor
:
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService
<h1>Procedural Logic Example</h1>
<button @onclick="@DoSomething">Do something important</button>
@code {
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
private async Task DoSomething()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user is not null)
{
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
// ...
}
if (user.IsInRole("Admin"))
{
// ...
}
if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
.Succeeded)
{
// ...
}
}
}
}
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService
<h1>Procedural Logic Example</h1>
<button @onclick="@DoSomething">Do something important</button>
@code {
[CascadingParameter]
private Task<AuthenticationState>? authenticationState { get; set; }
private async Task DoSomething()
{
if (authenticationState is not null)
{
var authState = await authenticationState;
var user = authState?.User;
if (user is not null)
{
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
// ...
}
if (user.IsInRole("Admin"))
{
// ...
}
if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
.Succeeded)
{
// ...
}
}
}
}
}
Solucionar problemas de erros
Erros comuns:
A autorização requer um parâmetro em cascata do tipo
Task<AuthenticationState>
. Considere usarCascadingAuthenticationState
para fornecer isso.O valor
null
é recebido paraauthenticationStateTask
Provavelmente, o projeto não foi criado usando um modelo Blazor do lado do servidor com a autenticação habilitada.
No .NET 7 ou versão anterior, encapsule um <CascadingAuthenticationState>
em torno de alguma parte da árvore da interface do usuário, por exemplo, em torno do roteador Blazor:
<CascadingAuthenticationState>
<Router ...>
...
</Router>
</CascadingAuthenticationState>
No .NET 8 ou versão posterior, não use o componente CascadingAuthenticationState:
- <CascadingAuthenticationState>
<Router ...>
...
</Router>
- </CascadingAuthenticationState>
Em vez disso, adicione serviços de estado de autenticação em cascata à coleção de serviços no arquivo Program
:
builder.Services.AddCascadingAuthenticationState();
O componente CascadingAuthenticationState (.NET 7 ou versão anterior) ou os serviços fornecidos pelo AddCascadingAuthenticationState (.NET 8 ou versão posterior) fornece o parâmetro Task<
AuthenticationState>
em cascata, que, por sua vez, recebe do serviço de injeção de dependência AuthenticationStateProvider subjacente.
PII (Informações de Identificação Pessoal)
A Microsoft usa a definição de GDPR para “dados pessoais” (GDPR 4.1) quando a documentação discute informações de identificação pessoal (PII).
PII refere-se a qualquer informação relacionada a uma pessoa natural identificada ou identificável. Uma pessoa natural identificável é aquela que pode ser identificada, direta ou indiretamente, com qualquer uma das seguintes opções:
- Nome
- Número de identificação
- Coordenadas de localização
- Identificador online
- Outros fatores específicos
- Físico
- Fisiológicos
- Genéticos
- Mentais (psicológicos)
- Económicos
- Cultural
- identity social
Recursos adicionais
- Documentação da plataforma de identity da Microsoft
- Tópicos de segurança do ASP.NET Core
- Configurar a Autenticação do Windows no ASP.NET Core
- Criar uma versão personalizada da biblioteca JavaScript Authentication.MSAL
- Awesome Blazor: links de exemplo da comunidade de autenticação
- Autenticação e autorização de Blazor Hybrid no ASP.NET Core
- Documentação da plataforma de identity da Microsoft
- Tópicos de segurança do ASP.NET Core
- Configurar a Autenticação do Windows no ASP.NET Core
- Criar uma versão personalizada da biblioteca JavaScript Authentication.MSAL
- Awesome Blazor: links de exemplo da comunidade de autenticação