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.
Note
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Warning
Esta versão do ASP.NET Core não é mais suportada. 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 10 deste artigo.
Este artigo descreve o suporte do ASP.NET Core para a configuração e o gerenciamento de segurança em aplicativos Blazor.
Blazor usa os mecanismos de autenticação ASP.NET Core existentes para estabelecer a identidade do usuário. O mecanismo exato depende de como o aplicativo Blazor está hospedado, do lado do servidor ou do lado do cliente.
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 podem impor regras de acesso para áreas do aplicativo e componentes. Como a execução de código do lado do cliente pode ser adulterada, não se pode confiar no código de autorização executado no cliente para impor absolutamente as regras de acesso ou controlar a exibição de conteúdo do lado do cliente.
Se a aplicação da regra de autorização precisar ser garantida, não implemente verificações de autorização no código do lado do cliente. Crie um Blazor Web App que confie unicamente na renderização do lado do servidor (SSR) para verificações de autorização e aplicação de regras.
Se a aplicação da regra 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.
Razor As convenções de autorização do Pages não se aplicam a componentes Razor navegáveis. Se um componente Razor não roteável estiver incorporado em uma página de um Razor aplicativo de Páginas, as convenções de autorização da página afetam indiretamente o Razor componente, juntamente com o restante do conteúdo da página.
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. Aplicações ASP.NET Core que utilizam o ASP.NET Core Identity para gestão de utilizadores devem usar Razor Páginas ao invés de componentes Razor para a interface do utilizador relacionada com Identity, como registo de utilizador, iniciar sessão, terminar sessão e outras tarefas de gestão de utilizadores. A criação de componentes Razor que lidam diretamente com Identity tarefas é possível para vários cenários, mas não é recomendada ou suportada pela Microsoft.
ASP.NET Abstrações principais, como SignInManager<TUser> e UserManager<TUser>, não são suportadas em componentes Razor. Para obter mais informações sobre como usar o ASP.NET Core Identity com Blazor, consulte Scaffold ASP.NET Core Identity num aplicativo Blazor do lado do servidor.
Note
Os exemplos de código neste artigo adotam tipos de referência anuláveis (NRTs) e análise estática de estado nulo do compilador .NET, que são suportados no ASP.NET Core no .NET 6 ou posterior. Ao direcionar para o .NET 5 ou versões anteriores, remova a designação de tipo nulo (?) dos exemplos neste artigo.
Mantenha dados e credenciais confidenciais com segurança
Não armazene segredos de aplicativos, cadeias de conexão, credenciais, senhas, números de identificação pessoal (PINs), código .NET/C# privado ou chaves/tokens privados no código do lado do cliente, que é sempre inseguro. O código Blazor do lado do cliente deve acessar serviços e bancos de dados seguros por meio de uma API da Web segura que você controla.
Em ambientes de teste/preparação e produção, o código Blazor do lado do servidor e as APIs da Web devem usar fluxos de autenticação seguros que evitem 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 Secret Manager é recomendada para proteger dados confidenciais. Para obter mais informações, consulte os seguintes recursos:
- Fluxos de autenticação seguros (documentação ASP.NET Core)
- Identidades gerenciadas para serviços do Microsoft Azure (este artigo)
Para desenvolvimento e testes locais do lado do cliente e 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 são autenticadas com segurança nos serviços do Azure sem armazenar credenciais no código do aplicativo. Para obter mais informações, consulte os seguintes recursos:
- O que são identidades gerenciadas para recursos do Azure? (Documentação do Microsoft Entra)
- Documentação dos serviços do Azure
Suporte antifalsificação
O modelo Blazor:
- Adiciona serviços antifalsificação automaticamente quando AddRazorComponents é chamado no arquivo
Program. - Adiciona o Antiforgery Middleware chamando UseAntiforgery na sua pipeline de processamento de pedidos no arquivo
Programe requisita proteção antifalsificação no endpoint com para mitigar as ameaças de falsificação de pedidos entre sites (CSRF/XSRF). 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 de formulário (EditForm). Para obter mais informações, consulte Visão geral ASP.NET formulários principaisBlazor.
O serviço AntiforgeryStateProvider fornece acesso a um token antifalsificação associado à sessão atual. Injete o serviço e chame o seu método GetAntiforgeryToken() para obter o AntiforgeryRequestToken atual. Para mais informações, consulte Chamar uma API da Web a partir de uma aplicação ASP.NET Core Blazor.
Blazor armazena tokens de solicitação no estado do componente, o que garante que os tokens antifalsificação estejam disponíveis para componentes interativos, mesmo quando eles não têm acesso à solicitação.
Note
A mitigação antifalsificação só é necessária ao enviar dados de formulário para o servidor codificado como , application/x-www-form-urlencoded, ou multipart/form-data, uma vez que estes são os únicos enctypes text/plain.
Para obter mais informações, consulte os seguintes recursos:
- Prevenir ataques de falsificação de solicitação entre sites (XSRF/CSRF) em ASP.NET Core: Este artigo é o principal sobre ASP.NET Core no assunto, que se aplica ao Blazor Server do lado do servidor, ao projeto de servidor de Blazor Web Apps e à integração de Blazor com páginas MVC/Razor.
ASP.NET Core : A secção de suporte a antifalsificaçãoVisão geral dos formulários do artigo refere-se ao suporte antifalsificação de formulários .
Autenticação de Blazor do lado do servidor
Os aplicativos Blazor do lado do servidor são configurados para segurança da mesma maneira que os aplicativos ASP.NET Core. Para obter mais informações, consulte os artigos em tópicos de segurança do ASP.NET Core.
O contexto de autenticação só é estabelecido quando a aplicação começa, que é quando a aplicação se conecta pela primeira vez ao WebSocket por uma ligação com o cliente. A autenticação pode ser baseada em um cookie ou em algum outro token de portador, mas a autenticação é gerenciada através do hub SignalR e inteiramente dentro do circuito . O contexto de autenticação é mantido durante o tempo de vida do circuito. Os aplicativos revalidam periodicamente o estado de autenticação do usuário a cada 30 minutos.
Se a aplicação precisar capturar usuários para serviços personalizados ou reagir a atualizações do usuário, consulte ASP.NET Core do lado do servidor e Blazor Web App cenários adicionais de segurança.
Blazor difere dos aplicativos Web renderizados por servidor tradicionais que fazem novas solicitações HTTP com cookies em cada navegação de página. A autenticação é verificada durante eventos de navegação. No entanto, os cookies não estão envolvidos. Os cookies só são enviados quando se faz um pedido HTTP a um servidor, o que não acontece quando o utilizador navega numa aplicação Blazor. Durante a navegação, o estado de autenticação do usuário é verificado dentro do Blazor circuito, que pode ser atualizado a qualquer momento no servidor usando a RevalidatingAuthenticationStateProvider abstração.
Important
A implementação de um NavigationManager personalizado para obter a validação de autenticação durante a navegação não é recomendada. Se a aplicação precisar executar uma lógica personalizada de estado de autenticação durante a navegação, use um AuthenticationStateProviderpersonalizado.
Note
Os exemplos de código neste artigo adotam tipos de referência anuláveis (NRTs) e análise estática de estado nulo do compilador .NET, que são suportados no ASP.NET Core no .NET 6 ou posterior. Quando o alvo é .NET 5 ou anterior, remova a designação de tipo nulo (?) dos exemplos neste artigo.
O serviço de AuthenticationStateProvider interno ou personalizado obtém dados de estado de autenticação do HttpContext.User do ASP.NET Core. É assim que o estado de autenticação se integra aos mecanismos de autenticação ASP.NET Core existentes.
Estado compartilhado
Os aplicativos Blazor do lado do servidor vivem na memória do servidor e várias sessões de aplicativos são hospedadas no mesmo processo. Para cada sessão de aplicativo, Blazor inicia um circuito com um escopo próprio de contêiner de injeção de dependências, portanto, os serviços de escopo são exclusivos por sessão de Blazor.
Warning
Não recomendamos que aplicações no mesmo servidor partilhem estado usando serviços singleton, a menos que seja tomado extremo cuidado, pois isso pode introduzir vulnerabilidades de segurança, como a divulgação do estado do utilizador entre circuitos.
Você pode usar serviços singleton com estado em aplicações Blazor se forem projetados 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 uma 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 vaza entre circuitos.
Para obter orientações gerais sobre o gerenciamento de estado, consulte ASP.NET Visão geral do gerenciamento de estado principalBlazor.
Segurança do lado do servidor de dados e credenciais confidenciais
Em ambientes de teste/preparação e produção, o código Blazor do lado do servidor e as APIs da Web devem usar fluxos de autenticação seguros que evitem 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 Secret Manager é recomendada para proteger dados confidenciais. Para obter mais informações, consulte os seguintes recursos:
- Fluxos de autenticação seguros (documentação ASP.NET Core)
- Identidades gerenciadas para serviços do Microsoft Azure (Blazor documentação)
Para desenvolvimento e testes locais do lado do cliente e do servidor, use a ferramenta Secret Manager para proteger credenciais confidenciais.
Modelo de projeto
Crie um novo aplicativo do lado Blazor do servidor seguindo as orientações em Ferramentas para ASP.NET Core Blazor.
Depois de escolher o modelo de aplicativo do lado do servidor e configurar o projeto, selecione a autenticação do aplicativo em Tipo de autenticação:
- Nenhum (padrão): Sem autenticação.
- Contas individuais: as contas de usuário são armazenadas no aplicativo usando ASP.NET Core Identity.
- Nenhum (padrão): Sem autenticação.
- Contas individuais: as contas de usuário são armazenadas no aplicativo usando ASP.NET Core Identity.
- Plataforma de identidade da Microsoft: Para obter mais informações, consulte os links na seção Recursos adicionais .
- Windows: Use a Autenticação do Windows.
Blazor Identity UI (Contas Individuais)
Quando se escolhe a opção de autenticação para Blazor, Blazor suporta a geração de uma interface do usuário completa baseada em Identity.
O modelo Blazor Web App serve de estrutura para o código Identity de um banco de dados de SQL Server. A versão de linha de comando usa SQLite e inclui um banco de dados SQLite para Identity.
O modelo:
- Suporta cenários interativos de renderização do lado do servidor (SSR interativo) e CSR (renderização do lado do cliente) com usuários autenticados.
- Adiciona IdentityRazor componentes e lógica relacionada para tarefas de autenticação de rotina, como entrar e sair de usuários. Os Identity componentes também suportam recursos avançados Identity , como confirmação de conta e recuperação de senha e autenticação multifator usando um aplicativo de terceiros. Observe que os próprios componentes Identity não suportam interatividade.
- Adiciona os pacotes e dependências relacionados ao Identity.
- Faz referência aos pacotes Identity em
_Imports.razor. - Cria uma classe de usuário Identity personalizada (
ApplicationUser). - Cria e registra um contexto de banco de dados EF Core (
ApplicationDbContext). - Configura o roteamento para as extremidades integradas de Identity.
- Inclui validação Identity e lógica de negócios.
Para inspecionar os componentes da estrutura do
Quando você escolhe os modos de renderização Interactive WebAssembly ou Interactive Auto, o servidor lida com todas as solicitações de autenticação e autorização, e os componentes Identity renderizam estaticamente no servidor no projeto principal do Blazor Web App.
O framework fornece uma AuthenticationStateProvider personalizada nos projetos de servidor e cliente (.Client) de modo a transmitir o estado de autenticação do utilizador para o navegador. O projeto de servidor chama AddAuthenticationStateSerialization, enquanto o projeto cliente chama AddAuthenticationStateDeserialization. A autenticação no servidor em vez do cliente permite que o aplicativo acesse o estado de autenticação durante a pré-renderização e antes que o tempo de execução do .NET WebAssembly seja inicializado. As implementações personalizadas de AuthenticationStateProvider usam o serviço de Estado de Componente Persistente (PersistentComponentState) para serializar o estado de autenticação em comentários HTML e para depois lê-lo de volta do WebAssembly, criando assim uma nova instância de AuthenticationState. Para obter mais informações, consulte a seção Gerenciar estado de autenticação em Blazor Web Apps .
Somente para soluções de Servidor Interativo, IdentityRevalidatingAuthenticationStateProvider (Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs) no projeto de servidor do modelo de projeto Blazor Web App (dotnet/aspnetcore repositório GitHub) é um componente do lado do servidor AuthenticationStateProvider que revalida o carimbo de segurança para o usuário conectado a cada 30 minutos enquanto o circuito interativo está conectado.
Quando você escolhe os modos de renderização Interactive WebAssembly ou Interactive Auto, o servidor lida com todas as solicitações de autenticação e autorização, e os componentes Identity renderizam estaticamente no servidor no projeto principal do Blazor Web App. O modelo de projeto inclui uma classe (fonte de referência) no projeto para sincronizar o estado de autenticação do utilizador entre o servidor e o navegador. A classe é uma implementação personalizada de AuthenticationStateProvider. O provedor usa o serviço de Estado Persistente do Componente (PersistentComponentState) para pré-renderizar o estado de autenticação e preservá-lo na página.
No projeto principal de um Blazor Web App, o provedor de estado de autenticação é nomeado IdentityRevalidatingAuthenticationStateProvider no diretório Components/Account do projeto de servidor no modelo de projeto Blazor Web App (dotnet/aspnetcore repositório GitHub) (aplicável apenas a soluções de interatividade do servidor) ou como PersistingRevalidatingAuthenticationStateProvider para soluções de interatividade WebAssembly ou Automática, no mesmo diretório.
Blazor Identity depende de DbContext instâncias não criadas por uma fábrica, o que é intencional porque DbContext é suficiente para que os Identity componentes do modelo de projeto sejam renderizados estaticamente sem oferecer suporte à interatividade.
Para obter uma descrição sobre como os modos de renderização interativos globais são aplicados a componentes nãoIdentity e, ao mesmo tempo, impõem SSR estático para os componentes Identity, consulte modos de renderização do ASP.NET Core Blazor.
Para obter mais informações sobre a persistência do estado pré-renderizado, consulte ASP.NET Persistência Blazor do estado pré-renderizado do núcleo.
Note
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma etiqueta para uma versão específica, use a lista suspensa Mudar ramificações ou etiquetas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Gerenciar o estado de autenticação no Blazor Web Apps
Esta secção aplica-se aos Blazor Web Appque adotam:
- Contas individuais
- Renderização do lado do cliente (CSR, interatividade suportada por WebAssembly).
Um provedor de estado de autenticação do lado do cliente é usado apenas dentro do Blazor e não está integrado ao sistema de autenticação ASP.NET Core. Durante a pré-renderização, Blazor respeita os metadados definidos na página e usa o sistema de autenticação ASP.NET Core para determinar se o usuário está autenticado. Quando um usuário navega de uma página para outra, um provedor de autenticação do lado do cliente é usado. Quando o usuário atualiza a página (recarga de página inteira), o provedor de estado de autenticação do lado do cliente não está envolvido na decisão de autenticação no servidor. Como o estado do usuário não é persistido pelo servidor, qualquer estado de autenticação mantido no lado do cliente é perdido.
Para resolver isso, a melhor abordagem é executar a autenticação dentro do sistema de autenticação ASP.NET Core. O provedor de estado de autenticação do lado do cliente cuida apenas de refletir o estado de autenticação do usuário. Exemplos de como fazer isso com provedores de estado de autenticação são demonstrados pelo modelo de projeto Blazor Web App e descritos abaixo.
No ficheiro
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
A API serializa apenas o nome do lado do servidor e as declarações de função para acesso no navegador. Para incluir todas as declarações, defina SerializeAllClaims como true na chamada do lado do servidor para AddAuthenticationStateSerialization:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization(
options => options.SerializeAllClaims = true);
No arquivo .Client do projeto cliente (Program), chame AddAuthenticationStateDeserialization, que adiciona um AuthenticationStateProvider onde o AuthenticationState é desserializado do servidor usando AuthenticationStateData e o serviço de Estado de Componente Persistente (PersistentComponentState). Deve haver uma chamada correspondente para AddAuthenticationStateSerialization no projeto de servidor.
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
PersistingRevalidatingAuthenticationStateProviderdotnet/aspnetcore(repositório GitHub): Para Blazor Web Apps que adotam renderização interativa do lado do servidor (SSR interativo) e renderização do lado do cliente (CSR). Este é um AuthenticationStateProvider do lado do servidor que revalida o carimbo de segurança para o utilizador conectado a cada 30 minutos em que um circuito interativo está conectado. Ele também utiliza o serviço de Estado do Componente Persistente para transferir o estado de autenticação para o cliente, que é então fixo durante toda a duração da CSR.PersistingServerAuthenticationStateProviderdotnet/aspnetcore(repositório GitHub): Para Blazor Web Apps que adotam apenas CSR. Este é um AuthenticationStateProvider do lado do servidor que usa o serviço de Estado Persistente do Componente para transferir o estado de autenticação para o cliente, que é então fixado durante toda a duração do CSR.PersistentAuthenticationStateProvider(dotnet/aspnetcorerepositório GitHub): Para Blazor Web Apps que adotam CSR. Este é um AuthenticationStateProvider do lado do cliente que determina o estado de autenticação do utilizador, procurando dados persistidos na página quando esta foi renderizada no servidor. Este estado de autenticação é fixo durante a duração do CSR. Se o usuário precisar fazer login ou logout, será necessário um recarregamento de página inteira. Isso fornece apenas um nome de usuário e e-mail para fins de exibição. Não inclui tokens para autenticação no servidor ao fazer pedidos subsequentes; isso é tratado separadamente usando um cookie incluído em pedidosHttpClientpara o servidor.
Note
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma etiqueta para uma versão específica, use a lista suspensa Mudar ramificações ou etiquetas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Andaime Identity
Para obter mais informações sobre scaffolding Identity num aplicativo do lado do servidor Blazor, consulte Scaffolding Identity em projetos ASP.NET Core.
Scaffold Identity num aplicativo Blazor do lado do servidor:
Reivindicações e tokens adicionais de fornecedores externos
Para armazenar adicionais declarações de provedores externos, consulte Como persistir declarações e tokens adicionais de provedores externos no ASP.NET Core.
Serviço de Aplicativo do Azure no Linux com Identity Server
Especifique o emissor explicitamente ao implementar no App Service do Azure no Linux com o Servidor Identity. Para obter mais informações, consulte Utilizar Identity para proteger um backend de API da Web para SPAs.
Injetar AuthenticationStateProvider para serviços com escopo de um componente
Não tente resolver AuthenticationStateProvider dentro de um escopo personalizado porque isso resulta na criação de uma nova instância do AuthenticationStateProvider que não foi inicializada corretamente.
Para aceder ao AuthenticationStateProvider dentro de um serviço com âmbito para um componente, injete o AuthenticationStateProvider no componente e passe-o para o serviço como um parâmetro. Essa abordagem garante que a instância correta e inicializada do AuthenticationStateProvider seja usada para cada instância do aplicativo do usuário.
ExampleService.cs:
public class ExampleService
{
public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
{
var authState = await authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
return $"{user.Identity.Name} is authenticated.";
}
else
{
return "The user is NOT authenticated.";
}
}
}
Registe o serviço com escopo definido. Em uma aplicação Blazor do lado do servidor, os serviços com escopo têm um tempo de vida igual à duração do circuito de conexão do cliente .
No ficheiro Program:
builder.Services.AddScoped<ExampleService>();
Em Startup.ConfigureServices de Startup.cs:
services.AddScoped<ExampleService>();
No seguinte componente InjectAuthStateProvider:
- O componente herda OwningComponentBase.
- O AuthenticationStateProvider é injetado e passado para
ExampleService.ExampleMethod. -
ExampleServiceé resolvido com OwningComponentBase.ScopedServices e GetRequiredService, que retorna a instância correta e inicializada deExampleServiceque existe ao longo do tempo de vida do circuito do usuário.
InjectAuthStateProvider.razor:
@page "/inject-auth-state-provider"
@inherits OwningComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase
<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>
<p>@message</p>
@code {
private string? message;
private ExampleService? ExampleService { get; set; }
protected override async Task OnInitializedAsync()
{
ExampleService = ScopedServices.GetRequiredService<ExampleService>();
message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
}
}
Para obter mais informações, consulte as orientações sobre OwningComponentBase em injeção de dependência do ASP.NET Core Blazor.
Exibição de conteúdo não autorizado durante a pré-renderização com um AuthenticationStateProvider personalizado
Para evitar mostrar conteúdo não autorizado, por exemplo, conteúdo num AuthorizeView componente, durante a pré-renderização com um AuthenticationStateProvider personalizado, adote uma das seguintes abordagens:
Implementar IHostEnvironmentAuthenticationStateProvider para o AuthenticationStateProvider personalizado para dar suporte à pré-renderização: Para um exemplo de implementação de IHostEnvironmentAuthenticationStateProvider, consulte a implementação Blazor da estrutura ServerAuthenticationStateProvider em
ServerAuthenticationStateProvider.cs(referência fonte).Note
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma etiqueta para uma versão específica, use a lista suspensa Mudar ramificações ou etiquetas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Desativar pré-renderização: indique o modo de renderização com o parâmetro
prerenderdefinido comofalseno componente de nível mais alto na hierarquia de componentes do aplicativo que não seja um componente raiz.Note
Não há suporte para tornar um componente raiz interativo, como o componente
App. Portanto, a pré-renderização não pode ser desabilitada diretamente pelo componenteApp.Para aplicativos baseados no modelo de projeto Blazor Web App, a pré-renderização normalmente é desabilitada quando o componente
Routesé usado no componenteApp(Components/App.razor) :<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />Além disso, desative a pré-renderização para o componente
HeadOutlet:<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />Você também pode controlar seletivamente o modo de renderização aplicado à instância do componente
Routes. Por exemplo, consulte os modos de renderização do ASP.NET Core Blazor.
Desativar a pré-renderização: abra o
_Host.cshtmlarquivo e altere orender-modeatributo do Component Tag Helper para Server:<component type="typeof(App)" render-mode="Server" />
- Autenticar o utilizador no servidor antes de a aplicação ser iniciada: para adotar esta abordagem, a aplicação deve responder à solicitação inicial de um utilizador com a página ou a vista de início de sessão baseada em Identitye impedir quaisquer solicitações para pontos de extremidade Blazor até que sejam autenticados. Para obter mais informações, consulte Criar um aplicativo ASP.NET Core com dados do usuário protegidos por autorização. Após a autenticação, o conteúdo não autorizado em componentes Razor pré-renderizados só é mostrado quando o usuário está realmente não autorizado a visualizar o conteúdo.
Gerenciamento de estado do usuário
Apesar da palavra "estado" no nome, AuthenticationStateProvider não é para armazenar o estado geral do usuário. AuthenticationStateProvider indica apenas o estado de autenticação do usuário para o aplicativo, se ele está conectado ao aplicativo e com quem está conectado.
A autenticação usa a mesma autenticação ASP.NET Core Identity que os aplicativos Razor Pages e MVC. O estado do usuário armazenado para ASP.NET Core Identity flui para Blazor sem adicionar código adicional ao aplicativo. Siga as orientações nos artigos e tutoriais do ASP.NET Core Identity para que os recursos de Identity entrem em vigor nas partes Blazor do aplicativo.
Para obter orientações sobre o gerenciamento geral do estado fora do ASP.NET CoreIdentity, consulte ASP.NET Visão geral do gerenciamento do estado principalBlazor.
Abstrações de segurança adicionais
Duas abstrações adicionais participam do gerenciamento do estado de autenticação:
ServerAuthenticationStateProvider (fonte de referência): um AuthenticationStateProvider usado pelo Blazor framework para obter o estado de autenticação a partir do servidor.
RevalidatingServerAuthenticationStateProvider (fonte de referência): uma classe base para AuthenticationStateProvider serviços usados pelo Blazor framework para receber um estado de autenticação do ambiente anfitrião e revalidá-lo em intervalos regulares.
Note
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma etiqueta para uma versão específica, use a lista suspensa Mudar ramificações ou etiquetas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Em aplicativos gerados a partir do Blazor modelo de projeto para .NET 8 ou posterior, ajuste o intervalo de revalidação padrão de 30 minutos em IdentityRevalidatingAuthenticationStateProvider. Antes do .NET 8, ajuste o intervalo em RevalidatingIdentityAuthenticationStateProvider. O exemplo a seguir reduz o intervalo para 20 minutos:
protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
Gestão do estado de autenticação ao terminar sessão
O Blazor do lado do servidor persiste o estado de autenticação do utilizador durante o tempo de vida do circuito, incluindo entre as abas do navegador. Para desconectar proativamente um utilizador nas guias do navegador quando o utilizador sair de uma guia, deve implementar um RevalidatingServerAuthenticationStateProvider (fonte de referência) com um RevalidationIntervalcurto.
Note
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma etiqueta para uma versão específica, use a lista suspensa Mudar ramificações ou etiquetas. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Duração da validade do URL de redirecionamento temporário
Esta secção aplica-se a Blazor Web Apps.
Use a opção RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration para obter ou definir o tempo de vida da validade do ASP.NET Core Data Protection para URLs de redirecionamento temporário emitidas pela renderização do lado do servidor Blazor. Eles são usados apenas transitoriamente, então o tempo de vida só precisa ser longo o suficiente para que um cliente receba a URL e comece a navegação para ela. No entanto, ele também deve ser longo o suficiente para permitir o desvio do relógio entre servidores. O valor padrão é cinco minutos.
No exemplo a seguir, o valor é estendido para sete minutos:
builder.Services.AddRazorComponents(options =>
options.TemporaryRedirectionUrlValidityDuration =
TimeSpan.FromMinutes(7));
Autenticação Blazor do lado do cliente
Nos aplicativos do cliente de Blazor, as verificações de autenticação no cliente podem ser ignoradas porque todo o código do cliente pode ser modificado pelos utilizadores. O mesmo vale para todas as tecnologias de aplicativos do lado do cliente, incluindo estruturas de SPA JavaScript e aplicativos nativos para qualquer sistema operacional.
Aditar o seguinte:
Uma referência de pacote para o pacote NuGet
Microsoft.AspNetCore.Components.Authorization.Note
Para obter orientação sobre como adicionar pacotes a aplicações .NET, consulte os artigos em Instalar e gerir pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.
O namespace Microsoft.AspNetCore.Components.Authorization para o ficheiro
_Imports.razordo aplicativo.
Para lidar com a autenticação, use o serviço de AuthenticationStateProvider interno ou personalizado.
Para obter mais informações sobre a autenticação do lado do cliente, consulte Secure ASP.NET Core Blazor WebAssembly.
Proteja os dados em Blazor Web App com renderização interativa automática
Quando um Blazor Web App adota a renderização do lado do servidor (SSR) e a renderização do lado do cliente (CSR) para componentes ou um aplicativo inteiro que especifica o modo de renderização automática interativa, a autorização para acessar componentes e dados é aplicada em dois locais. O componente restringe o acesso a si mesmo (e a quaisquer dados que obtenha) quando processado no servidor em virtude de um atributo de autorização no arquivo de definição do componente (@attribute [Authorize]). Quando o componente é renderizado no cliente, o acesso aos dados é restrito através dos endpoints da API web do servidor chamados do cliente. Deve-se ter cuidado ao proteger o acesso aos dados em ambos os locais para evitar o acesso indevido aos dados.
Considere o seguinte cenário em que dados meteorológicos seguros são exibidos por um componente. Demonstrações de algumas das seguintes abordagens podem ser avaliadas e testadas usando os BlazorWebAppEntra/BlazorWebAppEntraBffexemplos (.NET 9 ou posterior) ou osBlazorWebAppOidc/BlazorWebAppOidcBffexemplos (.NET 8 ou posterior) no Blazor repositório GitHub de exemplos (dotnet/blazor-samples) (como baixar).
O projeto cliente mantém uma classe WeatherForecast para armazenar dados meteorológicos:
public sealed class WeatherForecast(DateOnly date, int temperatureC, string summary)
{
public DateOnly Date { get; set; } = date;
public int TemperatureC { get; set; } = temperatureC;
public string? Summary { get; set; } = summary;
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
A interface IWeatherForecaster do projeto cliente define um método GetWeatherForecastAsync para obter dados meteorológicos:
public interface IWeatherForecaster
{
Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync();
}
O serviço de ClientWeatherForecaster do projeto cliente implementa IWeatherForecaster. O método GetWeatherForecastAsync chama uma API web no projeto do servidor no endpoint /weather-forecast para dados meteorológicos:
internal sealed class ClientWeatherForecaster(HttpClient httpClient)
: IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync() =>
await httpClient.GetFromJsonAsync<WeatherForecast[]>("/weather-forecast") ??
throw new IOException("No weather forecast!");
}
O projeto cliente mantém um componente Weather que:
- Impõe a autorização com um
[Authorize]atributo. - Usa o serviço de Estado do Componente Persistente (PersistentComponentState) para persistir os dados de previsão do tempo ao fazer a transição de SSR estático para interativo no servidor. Para obter mais informações, consulte Persistência de estado pré-renderizado do núcleo ASP.NETBlazor.
@page "/weather"
@using Microsoft.AspNetCore.Authorization
@using BlazorWebAppEntra.Client.Weather
@attribute [Authorize]
@inject IWeatherForecaster WeatherForecaster
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (Forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th aria-label="Temperature in Celsius">Temp. (C)</th>
<th aria-label="Temperature in Fahrenheit">Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in Forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
[PersistentState]
public IEnumerable<WeatherForecast>? Forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
Forecasts ??= await WeatherForecaster.GetWeatherForecastAsync();
}
}
@page "/weather"
@using Microsoft.AspNetCore.Authorization
@using BlazorWebAppEntra.Client.Weather
@attribute [Authorize]
@implements IDisposable
@inject PersistentComponentState ApplicationState
@inject IWeatherForecaster WeatherForecaster
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th aria-label="Temperature in Celsius">Temp. (C)</th>
<th aria-label="Temperature in Fahrenheit">Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private IEnumerable<WeatherForecast>? forecasts;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<IEnumerable<WeatherForecast>>(
nameof(forecasts), out var restoredData))
{
forecasts = await WeatherForecaster.GetWeatherForecastAsync();
}
else
{
forecasts = restoredData!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose() => persistingSubscription.Dispose();
}
O projeto de servidor implementa IWeatherForecaster como ServerWeatherForecaster, o que gera e retorna dados meteorológicos através do seu método GetWeatherForecastAsync.
internal sealed class ServerWeatherForecaster() : IWeatherForecaster
{
public readonly string[] summaries =
[
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot",
"Sweltering", "Scorching"
];
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
return Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
}
}
Se o aplicativo precisar chamar uma API da Web externa para obter os dados meteorológicos, você poderá injetar um cliente HTTP (HttpClient) para solicitar os dados:
internal sealed class ServerWeatherForecaster(HttpClient httpClient,
IHttpContextAccessor httpContextAccessor) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
var httpContext = httpContextAccessor.HttpContext ??
throw new InvalidOperationException("No HttpContext!");
var accessToken = await httpContext.GetTokenAsync("access_token") ??
throw new InvalidOperationException("No access_token was saved");
using var request =
new HttpRequestMessage(HttpMethod.Get, "/weather-forecast");
request.Headers.Authorization = new("Bearer", accessToken);
using var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
Em outra abordagem, pode-se injetar uma fábrica de clientes HTTP (IHttpClientFactory) no ServerWeatherForecaster e chamar uma API da Web externa usando um cliente HTTP nomeado com um manipulador de token. Para mais informações, consulte Chamar uma API da Web a partir de uma aplicação ASP.NET Core Blazor.
Se o aplicativo usa a plataforma de identidade da Microsoft com pacotes da Web da Microsoft Identity para oMicrosoft Entra ID (consulte Chamar uma API da Web de um aplicativo ASP.NET CoreBlazor), o seguinte ServerWeatherForecaster demonstra como fazer uma chamada de API da Web externa. O token de acesso é automaticamente anexado à solicitação.
internal sealed class ServerWeatherForecaster(IDownstreamApi downstreamApi) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
using var response = await downstreamApi.CallApiForUserAsync("DownstreamApi",
options =>
{
options.RelativePath = "/weather-forecast";
});
return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
Independentemente da abordagem adotada pelo ServerWeatherForecaster para obter os dados, o projeto de servidor mantém um ponto de extremidade de API da Web seguro para chamadas de dados meteorológicos do cliente. Este endpoint resulta em uma ServerWeatherForecaster.GetWeatherForecastAsync invocação no servidor.
app.MapGet("/weather-forecast", (
[FromServices] IWeatherForecaster WeatherForecaster) =>
{
return WeatherForecaster.GetWeatherForecastAsync();
}).RequireAuthorization();
Usando a abordagem anterior, existem dois sistemas para fornecer dados meteorológicos seguros ao usuário:
- Quando o
Weathercomponente é renderizado no servidor, oServerWeatherForecastermétodo doGetWeatherForecastAsyncserviço é usado diretamente para obter os dados meteorológicos. A segurança dos dados é garantida pelo atributo do componente. Em resumo, a segurança dos dados meteorológicos é imposta pelo componente. - Quando o componente
Weatheré renderizado nodo cliente, o serviçoClientWeatherForecasteré usado para fazer uma chamada à API da Web para o ponto de extremidade seguro/weather-forecastque aplica o método de extensão RequireAuthorization. Se o utilizador tiver autorização para aceder aos dados meteorológicos, o ponto de extremidade usa o serviçoServerWeatherForecasterpara ligar paraGetWeatherForecastAsync. Os dados são devolvidos ao cliente. O servidor garante a segurança dos dados meteorológicos através do uso do endpoint da sua API web.
A abordagem anterior funciona bem quando os requisitos de segurança da API da Web correspondem aos requisitos de segurança do componente. Por exemplo, a mesma política de autorização pode ser aplicada ao ponto de extremidade da API da Web e ao componente.
Cenários complexos exigem planejamento e implementação adicionais. Por exemplo, uma API Web de servidor que tenha vários chamadores com permissões de acesso diferentes requer uma política de autorização mais sofisticada, uma ou mais políticas adicionais ou pontos de extremidade adicionais com requisitos de acesso diferentes.
Ao integrar segurança nos aplicativos que adotam renderização automática interativa, lembre-se de que a segurança implementada para os pontos de extremidade da API Web do servidor não protege a implementação do serviço do servidor usada quando um componente é renderizado no servidor e acessa dados através do serviço. Pese cuidadosamente a diferença entre acessar dados no servidor durante o SSR versus acessar os dados em uma solicitação de API da Web do cliente durante o CSR. Aplique estrategicamente a segurança para evitar o acesso indevido aos dados.
Exemplos no repositório do GitHub Blazor (dotnet/blazor-samples) (como fazer download) que demonstram a abordagem descrita nesta seção:
BlazorWebAppOidcBlazorWebAppOidcBffBlazorWebAppEntraBlazorWebAppEntraBff
AuthenticationStateProvider serviço
AuthenticationStateProvider é o serviço subjacente usado pelo componente AuthorizeView e serviços de autenticação em cascata para obter o estado de autenticação para um usuário.
AuthenticationStateProvider é o serviço subjacente usado pelo componente AuthorizeView e pelo componente CascadingAuthenticationState para obter o estado de autenticação de um usuário.
Normalmente, você não usa AuthenticationStateProvider diretamente. Use o componente AuthorizeView ou as abordagens Task<AuthenticationState> descritas posteriormente neste artigo. A principal desvantagem de usar AuthenticationStateProvider diretamente é que o componente não é notificado automaticamente se os dados do estado de autenticação subjacente forem alterados.
Para implementar um AuthenticationStateProvider personalizado, consulte ASP.NET Core Blazor de estado de autenticação, que inclui orientações sobre como implementar notificações de alteração do estado de autenticação do utilizador.
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 porque o usuário é um ClaimsPrincipal, as declarações podem ser enumeradas e a associação em funções avaliada.
Para obter mais informações sobre injeção de dependência (DI) e serviços, consulte injeção de dependência do ASP.NET Core Blazor e Injeção de dependência no ASP.NET Core. Para obter informações sobre como implementar um AuthenticationStateProvider personalizado, consulte o estado de autenticação no ASP.NET CoreBlazor.
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 processual, como ao executar uma ação acionada pelo usuário, obtenha os dados do estado de autenticação definindo um parâmetro em cascata do tipo Task<AuthenticationState>, como demonstra o 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, as afirmações podem ser enumeradas e a participação em funções ser avaliada.
Configure o parâmetro em cascata Task<AuthenticationState> usando os serviços de autenticação em cascata e de estado AuthorizeRouteView.
Quando você cria 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. Uma aplicação Blazor no lado cliente também inclui os registos de serviço necessários. Informações adicionais são apresentadas na seção Personalizar o 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();
Configure o parâmetro em cascata Task<AuthenticationState> usando os componentes AuthorizeRouteView e CascadingAuthenticationState.
Quando você cria um aplicativo Blazor a partir de um dos Blazor modelos de projeto com a autenticação habilitada, o aplicativo inclui os componentes AuthorizeRouteView e CascadingAuthenticationState mostrados no exemplo a seguir. Uma aplicação Blazor no lado cliente também inclui os registos de serviço necessários. Informações adicionais são apresentadas na seção Personalizar o conteúdo não autorizado com o componente Router.
<CascadingAuthenticationState>
<Router ...>
<Found ...>
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
...
</Found>
</Router>
</CascadingAuthenticationState>
Note
Com o lançamento do .NET 5.0.1 e para quaisquer versões adicionais do 5.x, o Router componente inclui o PreferExactMatches parâmetro definido como @true. Para obter mais informações, consulte Migrar do ASP.NET Core 3.1 para o .NET 5.
Num aplicativo cliente Blazor, adicione serviços de autorização ao ficheiro Program:
builder.Services.AddAuthorizationCore();
Num app Blazor do lado do cliente, adicione opções assim como serviços de autorização ao ficheiro Program.
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
Em um aplicativo de Blazor do lado do servidor, os serviços de opções e autorização já estão presentes, portanto, nenhuma etapa adicional é necessária.
Authorization
Depois que um usuário é autenticado, as regras de autorização são aplicadas para controlar o que o usuário pode fazer.
Normalmente, o acesso é concedido ou negado com base no seguinte:
- Um usuário é autenticado (conectado).
- Um utilizador está numa função .
- Um utilizador tem uma reivindicação .
- Uma política é satisfeita.
Cada um desses conceitos é o mesmo que em um aplicativo ASP.NET Core MVC ou Razor Pages. Para obter mais informações sobre a segurança ASP.NET Core, consulte os artigos em ASP.NET Core Security e Identity.
componente AuthorizeView
O componente AuthorizeView exibe seletivamente o conteúdo da interface do usuário, dependendo se o usuário está autorizado. Essa abordagem é útil quando você só precisa exibir dados para o usuário e não precisa usar a identidade do usuário na lógica processual.
O componente expõe uma variável context do tipo AuthenticationState (@context na sintaxe Razor), que você pode usar 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 componente AuthorizeView 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 método HandleClick é associado apenas a um botão visível para usuários autorizados, mas nada impede que esse método seja invocado de outros lugares. Para garantir a segurança no nível do método, implemente uma lógica de autorização adicional no próprio manipulador ou na API relevante.
Razor componentes do Blazor Web Appnunca exibem conteúdo <NotAuthorized> quando a autorização falha durante a renderização estática no servidor (SSR estático). O pipeline do ASP.NET Core do lado do servidor processa a autorização no servidor. Use técnicas do lado do servidor, como configurar LoginPath para lidar com pedidos não autorizados. Para obter mais informações, consulte modos de renderização do ASP.NET Core Blazor.
Warning
Os elementos de marcação e os métodos do lado do cliente associados a um AuthorizeView só são protegidos contra exibição e execução na interface do usuário renderizada em aplicativos do lado do cliente Blazor. Para proteger o conteúdo autorizado e métodos seguros no Blazordo lado do cliente, o conteúdo geralmente é fornecido por uma chamada de API da Web segura e autorizada para uma API de servidor e nunca é armazenado no aplicativo. Para obter mais informações, consulte Chamar uma API da Web de uma aplicação ASP.NET Core Blazor e cenários de segurança adicionais do ASP.NET CoreBlazor 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 as opções ou o acesso da interface do usuário, são abordadas na seção de autorização.
Se as condições de autorização não forem especificadas, AuthorizeView usará uma política padrão:
- Os usuários autenticados (conectados) são autorizados.
- Os usuários não autenticados (desconectados) não são autorizados.
O componente AuthorizeView pode ser usado no componente NavMenu (Shared/NavMenu.razor) para exibir o componente NavLink (NavLink), mas observe que este método 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 políticas
O componente
Para autorização baseada em função, 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 utilizador 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 define um Context para o componente interno AuthorizeView, de forma a evitar uma colisão no contexto AuthenticationState. O contexto AuthenticationState é acedido na AuthorizeView externa com o método padrão para aceder ao contexto (@context.User). O contexto na AuthorizeView interna é acessado 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 parâmetro Policy com um único nome de política:
<AuthorizeView Policy="Over21">
<p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>
Para lidar com o caso em que o usuário deve satisfazer uma das várias políticas, crie uma política que confirme que o usuário satisfaz outras políticas.
Para lidar com o caso em que o usuário deve satisfazer várias políticas simultaneamente, execute uma das seguintes abordagens:
Crie uma política para AuthorizeView que confirme que o usuário satisfaz várias outras políticas.
Incorporar 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 exija que os usuários tenham uma determinada declaração. Para obter mais informações, consulte Autorização baseada em políticas no ASP.NET Core.
Se tanto Roles como Policy forem definidos, a autorização só será bem-sucedida quando ambas as condições forem satisfeitas. Ou seja, o usuário deve pertencer a pelo menos uma das funções especificadas e atender aos requisitos definidos pela política.
Se nem Roles nem Policy for especificado, AuthorizeView usará a política padrão:
- Os usuários autenticados (conectados) são autorizados.
- Os usuários não autenticados (desconectados) não são autorizados.
Como as strings .NET são sensíveis a maiúsculas e minúsculas, a correspondência de nomes de função e política também é sensível a maiúsculas e 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ções e políticas (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 e políticas é incomum, mas permitido pela estrutura. Por exemplo, billing administrator é um formato de nome de política ou função incomum em aplicativos .NET, mas é um nome de função ou política válido.
Conteúdo exibido durante a autenticação assíncrona
Blazor permite que o estado de autenticação seja determinado de forma assíncrona. O cenário principal para esta abordagem é em aplicações de Blazor do lado do cliente que fazem uma solicitação a um ponto de extremidade externo para autenticação.
Enquanto a autenticação está em andamento, AuthorizeView não exibe conteúdo. Para exibir conteúdo enquanto a autenticação ocorre, atribua o 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>
Essa abordagem normalmente não é aplicável a aplicativos de Blazor do lado do servidor. Os aplicativos Blazor do lado do servidor conhecem o estado de autenticação assim que o estado é estabelecido. O conteúdo Authorizing pode ser fornecido no componente AuthorizeView de um aplicativo, mas nunca é exibido.
[Authorize] atributo
O [Authorize] atributo está disponível em Razor componentes:
@page "/"
@attribute [Authorize]
You can only see this if you're signed in.
Important
Utilize apenas [Authorize] em componentes @page alcançados através do roteador Blazor. A autorização é executada apenas como um aspeto do roteamento e não para componentes-filho renderizados numa página. Para autorizar a exibição de partes específicas dentro de uma página, use AuthorizeView em vez disso.
O [Authorize] atributo também oferece suporte à autorização baseada em função ou política. Para autorização baseada em função, 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 autorização baseada em política, use o parâmetro Policy:
@page "/"
@attribute [Authorize(Policy = "Over21")]
<p>You can only see this if you satisfy the 'Over21' policy.</p>
Se nem Roles nem Policy for especificado, [Authorize] usará a política padrão:
- Os usuários autenticados (conectados) são autorizados.
- Os usuários não autenticados (desconectados) não são autorizados.
Quando o usuário não está autorizado e se o aplicativo não personaliza conteúdo não autorizado com o Router componente, a estrutura exibe 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 do Router.Found para 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
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 permitem que a lógica personalizada tome decisões de autorização.
No exemplo a seguir, uma política de 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, armazenevaluecomo uma cadeia de caracteres ou defina um valor de cadeia de caracteres vazio (string.Empty). - Se
idnão for uma cadeia de caracteres vazia, afirme que a política está satisfeita (retornartrue) se o valor da cadeia começar comEMP. Caso contrário, afirme que a política falha (retornarfalse).
No ficheiro 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 excessivamente simplificada, usada apenas para demonstrar o conceito com um exemplo de trabalho. Para obter mais informações sobre como criar e configurar políticas de autorização, consulte Autorização baseada em políticas no ASP.NET Core.
No componente EditUser seguinte, o recurso em /users/{id}/edit tem um parâmetro de rota para o identificador do utilizador ({id}). O componente utiliza a anterior política de autorização de EditUser para ver se o valor de rota para id começa com EMP. Se id começar com EMP, a política será bem-sucedida e o acesso ao componente será autorizado. Se id começar com um valor diferente de 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 conteúdo não autorizado com o componente Router
O componente Router, em conjunto com o componente AuthorizeRouteView, permite que o aplicativo especifique conteúdo personalizado se:
- O usuário falha uma condição de
[Authorize]aplicada ao componente. A marcação do elemento<NotAuthorized>é exibida. O atributo[Authorize]é abordado na seção atributo[Authorize]. - A autorização assíncrona está em andamento, o que geralmente significa que o processo de autenticação do usuário está em andamento. A marcação do elemento
<Authorizing>é exibida.
Important
Os recursos do roteador Blazor que exibem conteúdo <NotAuthorized> e <NotFound> não estão a funcionar durante a renderização estática do lado do servidor (SSR estático) porque o processamento de solicitações é totalmente gerido pelo 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 incorretas durante o SSR estático. Para obter mais informações, consulte modos de renderização do ASP.NET Core Blazor.
<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.
Note
O anterior requer o registro de 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, Authorizede NotAuthorized pode incluir itens arbitrários, como outros componentes interativos.
Se o conteúdo NotAuthorized não for especificado, o AuthorizeRouteView usará a seguinte mensagem de substituição:
Not authorized.
Um aplicativo criado a partir do modelo de projeto Blazor WebAssembly com 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 identidade.
Lógica processual
Se for necessário que o aplicativo verifique as regras de autorização como parte da lógica processual, use um parâmetro em cascata do tipo Task<AuthenticationState> para obter a ClaimsPrincipaldo usuário.
Task<
AuthenticationState
> pode ser combinado com outros serviços, como IAuthorizationService, para avaliar políticas.
No exemplo a seguir:
- O
user.Identity.IsAuthenticatedexecuta código para usuários autenticados (conectados). - O
user.IsInRole("admin")executa código para usuários na função 'Admin'. - O
(await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeededexecuta código para utilizadores que cumpram os requisitos da política '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 de 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 erros
Erros comuns:
A autorização requer um parâmetro em cascata do tipo
Task<AuthenticationState>. Considere usarCascadingAuthenticationStatepara fornecer isso.nullvalor é recebido paraauthenticationStateTask
É provável que o projeto não tenha sido criado usando um modelo de Blazor do lado do servidor com autenticação habilitada.
No .NET 7 ou anterior, envolva uma <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 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();
Os serviços fornecidos pelo componente CascadingAuthenticationState (.NET 7 ou anterior) ou pelo AddCascadingAuthenticationState (.NET 8 ou posterior) fornecem o parâmetro em cascata Task<AuthenticationState>, que, por sua vez, recebe do serviço subjacente de injeção de dependência AuthenticationStateProvider.
Informações de identificação pessoal (PII)
A Microsoft usa a definição do 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 relativa a uma pessoa singular identificada ou identificável. Uma pessoa singular identificável é aquela que possa ser identificada, direta ou indiretamente, com qualquer um dos seguintes elementos:
- Name
- Número de identificação
- Coordenadas de localização
- Identificador em linha
- Outros fatores específicos
- Physical
- Physiological
- Genetic
- Mental (psicológico)
- Economic
- Cultural
- Identidade social
Recursos adicionais
- Recursos do servidor e do Blazor Web App
- Guia de início rápido: adicionar início de sessão com a Microsoft a uma aplicação Web ASP.NET Core
- Guia de início rápido: proteja uma API Web ASP.NET Core com a plataforma de identidade da Microsoft
-
Configure o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga: Inclui orientações sobre:
- Usar o Middleware de Cabeçalhos Reencaminhados para manter as informações do esquema HTTPS em servidores proxy e redes internas.
- Cenários e casos de uso adicionais, incluindo configuração manual do esquema, alterações de caminho de pedido para o roteamento correto das solicitações e o encaminhamento do esquema de pedido para proxies reversos em Linux e não-IIS.
- Documentação da plataforma de identidade da Microsoft
- ASP.NET Principais tópicos de segurança
- Configurar a autenticação do Windows no ASP.NET Core
- IHttpContextAccessor/HttpContext em aplicativos ASP.NET Core Blazor
- Crie uma versão personalizada da biblioteca JavaScript Authentication.MSAL
- Awesome Blazor: Autenticação exemplos de links da comunidade
- Autenticação e autorização ASP.NET Core Blazor Hybrid
- Recursos de Blazor do lado do servidor
- Guia de início rápido: adicionar início de sessão com a Microsoft a uma aplicação Web ASP.NET Core
- Guia de início rápido: proteja uma API Web ASP.NET Core com a plataforma de identidade da Microsoft
-
Configure o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga: Inclui orientações sobre:
- Usar o Middleware de Cabeçalhos Reencaminhados para manter as informações do esquema HTTPS em servidores proxy e redes internas.
- Cenários e casos de uso adicionais, incluindo configuração manual do esquema, alterações de caminho de pedido para o roteamento correto das solicitações e o encaminhamento do esquema de pedido para proxies reversos em Linux e não-IIS.
- Documentação da plataforma de identidade da Microsoft
- ASP.NET Principais tópicos de segurança
- IHttpContextAccessor/HttpContext em aplicativos ASP.NET Core Blazor
- Configurar a autenticação do Windows no ASP.NET Core
- Crie uma versão personalizada da biblioteca JavaScript Authentication.MSAL
- Awesome Blazor: Autenticação exemplos de links da comunidade