Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
Há tantos aspectos sobre segurança em microsserviços e aplicativos Web que o tópico poderia facilmente levar vários livros como este. Portanto, nesta seção, nos concentraremos em autenticação, autorização e segredos do aplicativo.
Implementar a autenticação em microsserviços e aplicativos Web do .NET
Geralmente, é necessário que recursos e APIs publicados por um serviço sejam limitados a determinados usuários ou clientes confiáveis. A primeira etapa para tomar esses tipos de decisões de confiança no nível da API é a autenticação. A autenticação é o processo de verificação confiável da identidade de um usuário.
Em cenários de microsserviço, a autenticação é normalmente feita de forma centralizada. Se você estiver usando um Gateway de API, o gateway será um bom lugar para se autenticar, conforme mostrado na Figura 9-1. Se você usar essa abordagem, verifique se os microsserviços individuais não podem ser acessados diretamente (sem o Gateway de API), a menos que haja segurança adicional para autenticar mensagens, sejam elas provenientes do gateway ou não.
Figura 9-1. Autenticação centralizada com um Gateway de API
Quando o Gateway de API centraliza a autenticação, ele adiciona informações do usuário ao encaminhar solicitações para os microsserviços. Se os serviços puderem ser acessados diretamente, um serviço de autenticação como o Azure Active Directory ou um microsserviço de autenticação dedicado atuando como um STS (serviço de token de segurança) poderá ser usado para autenticar usuários. As decisões de confiança são compartilhadas entre os serviços com tokens de segurança ou cookies. (Esses tokens podem ser compartilhados entre aplicativos ASP.NET Core, se necessário, implementando o compartilhamento de cookie.) Esse padrão é ilustrado na Figura 9-2.
Figura 9-2. Autenticação por microsserviço de identidade; a confiança é compartilhada usando um token de autorização
Quando os microsserviços são acessados diretamente, a confiança, que inclui autenticação e autorização, é tratada por um token de segurança emitido por um microsserviço dedicado, compartilhado entre microsserviços.
Autenticar com o ASP.NET Core Identity
O principal mecanismo no ASP.NET Core para identificar os usuários de um aplicativo é o sistema de associação ASP.NET Core Identity . A Identidade do ASP.NET Core armazena informações de usuário (incluindo informações de logon, funções e declarações) em um repositório de dados configurado pelo desenvolvedor. Normalmente, o armazenamento de dados do ASP.NET Core Identity é um repositório do Entity Framework fornecido no Microsoft.AspNetCore.Identity.EntityFrameworkCore pacote. No entanto, repositórios personalizados ou outros pacotes de terceiros podem ser usados para armazenar informações de identidade no Armazenamento de Tabelas do Azure, no CosmosDB ou em outros locais.
Dica
ASP.NET Core 2.1 e posterior fornece ASP.NET Core Identity como uma Biblioteca de Classes Razor, portanto, você não verá muito do código necessário em seu projeto, como foi o caso das versões anteriores. Para obter detalhes sobre como personalizar o código de identidade para atender às suas necessidades, consulte Scaffold Identity em projetos do ASP.NET Core.
O código a seguir é obtido do modelo de projeto MVC do aplicativo Web ASP.NET Core com a autenticação de conta de usuário individual selecionada. Ele mostra como configurar ASP.NET Identidade Principal usando o Entity Framework Core no arquivo Program.cs .
//...
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
//...
Depois que ASP.NET Core Identity estiver configurado, você a habilitará adicionando o app.UseAuthentication() e o endpoints.MapRazorPages(), conforme mostrado no exemplo de código a seguir no arquivo Program.cs do serviço.
//...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
//...
Importante
As linhas no código anterior devem estar na ordem mostrada para que a identidade funcione corretamente.
O uso do ASP.NET Core Identity permite vários cenários:
Crie novas informações de usuário usando o tipo UserManager (userManager.CreateAsync).
Autenticar usuários usando o tipo SignInManager. Você pode usar
signInManager.SignInAsyncpara entrar diretamente ousignInManager.PasswordSignInAsyncpara confirmar se a senha do usuário está correta e, em seguida, fazer login.Identifique um usuário com base nas informações armazenadas em um cookie (que é lido por ASP.NET middleware core identity) para que as solicitações subsequentes de um navegador incluam a identidade e as declarações de um usuário conectado.
ASP.NET Core Identity também dá suporte à autenticação de dois fatores.
Para cenários de autenticação que fazem uso de um armazenamento de dados de usuário local e que persistem a identidade entre solicitações usando cookies (como é típico para aplicativos Web MVC), ASP.NET Core Identity é uma solução recomendada.
Autenticar com provedores externos
ASP.NET Core também dá suporte ao uso de provedores de autenticação externa para permitir que os usuários entrem por meio de fluxos OAuth 2.0 . Isso significa que os usuários podem entrar usando processos de autenticação existentes de provedores como Microsoft, Google, Facebook ou Twitter e associar essas identidades a uma identidade ASP.NET Core em seu aplicativo.
Para usar a autenticação externa, além de incluir o middleware de autenticação, conforme mencionado anteriormente, usando o app.UseAuthentication() método, você também precisa registrar o provedor externo no Program.cs conforme mostrado no exemplo a seguir:
//...
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication()
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
microsoftOptions.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
})
.AddGoogle(googleOptions => { ... })
.AddTwitter(twitterOptions => { ... })
.AddFacebook(facebookOptions => { ... });
//...
Provedores de autenticação externa populares e seus pacotes NuGet associados são mostrados na tabela a seguir:
| Provedor | Pacote |
|---|---|
| Microsoft | Microsoft.AspNetCore.Authentication.MicrosoftAccount |
| Microsoft.AspNetCore.Authentication.Google | |
| Microsoft.AspNetCore.Authentication.Facebook | |
| Gorjeio | Microsoft.AspNetCore.Authentication.Twitter |
Em todos os casos, você deve concluir um procedimento de registro de aplicativo dependente do fornecedor e que geralmente envolve:
- Obtendo uma ID do aplicativo cliente.
- Obtendo uma chave secreta do cliente de aplicativo.
- Configurando uma URL de redirecionamento, que é tratada pelo middleware de autorização e pelo provedor registrado
- Opcionalmente, configure uma URL de saída para lidar corretamente com a saída em um cenário de Logon Único (SSO).
Para obter detalhes sobre como configurar seu aplicativo para um provedor externo, consulte a autenticação do provedor externo na documentação do ASP.NET Core).
Dica
Todos os detalhes são tratados pelo middleware de autorização e pelos serviços mencionados anteriormente. Portanto, você só precisa escolher a opção de autenticação da Conta de Usuário Individual ao criar o projeto de aplicativo Web ASP.NET Core no Visual Studio, conforme mostrado na Figura 9-3, além de registrar os provedores de autenticação mencionados anteriormente.
Figura 9-3. Selecionando a opção Contas de Usuário Individuais, para usar a autenticação externa, ao criar um projeto de aplicativo Web no Visual Studio 2019.
Além dos provedores de autenticação externos listados anteriormente, há pacotes de terceiros disponíveis que fornecem middleware para usar muitos outros provedores de autenticação externos. Para obter uma lista, consulte o repositório AspNet.Security.OAuth.Providers no GitHub.
Você também pode criar seu próprio middleware de autenticação externa para resolver algumas necessidades especiais.
Autenticar com tokens de portador
A autenticação com ASP.NET Identidade Principal (ou Identidade mais provedores de autenticação externa) funciona bem para muitos cenários de aplicativo Web nos quais armazenar informações do usuário em um cookie é apropriado. Em outros cenários, porém, os cookies não são um meio natural de persistir e transmitir dados.
Por exemplo, em uma API Web do ASP.NET Core que expõe pontos de extremidade RESTful que podem ser acessados por SPAs (Aplicativos de Página Única), por clientes nativos ou até mesmo por outras APIs Web, você normalmente deseja usar a autenticação de token de portador. Esses tipos de aplicativos não funcionam com cookies, mas podem recuperar facilmente um token de portador e incluí-lo no cabeçalho de autorização de solicitações subsequentes. Para habilitar a autenticação de token, o ASP.NET Core dá suporte a várias opções para usar o OAuth 2.0 e o OpenID Connect.
Autenticar com um provedor de identidade OpenID Connect ou OAuth 2.0
Se as informações do usuário forem armazenadas no Azure Active Directory ou em outra solução de identidade que dê suporte ao OpenID Connect ou ao OAuth 2.0, você poderá usar o pacote Microsoft.AspNetCore.Authentication.OpenIdConnect para autenticar usando o fluxo de trabalho do OpenID Connect. Por exemplo, para se autenticar no microsserviço Identity.Api no eShopOnContainers, um aplicativo Web ASP.NET Core pode usar o middleware desse pacote, conforme mostrado no exemplo simplificado a seguir em Program.cs:
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
var callBackUrl = builder.Configuration.GetValue<string>("CallBackUrl");
var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60);
// Add Authentication services
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime))
.AddOpenIdConnect(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = identityUrl.ToString();
options.SignedOutRedirectUri = callBackUrl.ToString();
options.ClientId = useLoadTest ? "mvctest" : "mvc";
options.ClientSecret = "secret";
options.ResponseType = useLoadTest ? "code id_token token" : "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.RequireHttpsMetadata = false;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("orders");
options.Scope.Add("basket");
options.Scope.Add("marketing");
options.Scope.Add("locations");
options.Scope.Add("webshoppingagg");
options.Scope.Add("orders.signalrhub");
});
// Build the app
//…
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
Quando você usa esse fluxo de trabalho, o middleware do ASP.NET Core Identity não é necessário, pois todo o armazenamento e a autenticação de informações do usuário são tratados pelo serviço identidade.
Emitir tokens de segurança de um serviço do ASP.NET Core
Se você preferir emitir tokens de segurança para usuários locais do ASP.NET Core Identity em vez de usar um provedor de identidade externo, poderá aproveitar algumas boas bibliotecas de terceiros.
IdentityServer4 e OpenIddict são provedores OpenID Connect que se integram facilmente ao ASP.NET Core Identity para que você possa emitir tokens de segurança de um serviço ASP.NET Core. A documentação do IdentityServer4 tem instruções detalhadas para usar a biblioteca. No entanto, as etapas básicas para usar o IdentityServer4 para emitir tokens são as seguintes.
Configure o IdentityServer4 em Program.cs fazendo uma chamada ao construtor. Services.AddIdentityServer.
Você chama o app.UseIdentityServer no Program.cs para adicionar o IdentityServer4 ao pipeline de processamento de requisições HTTP do aplicativo. Isso permite à biblioteca atender a solicitações para endpoints OpenID Connect e OAuth2, como /connect/token.
Configure o servidor de identidade definindo os seguintes dados:
As credenciais a serem usadas para assinatura.
Os recursos de Identidade e API aos quais os usuários podem solicitar acesso:
Os recursos de API representam dados protegidos ou funcionalidade que um usuário pode acessar com um token de acesso. Um exemplo de um recurso de API seria uma API Web (ou um conjunto de APIs) que requer autorização.
Os recursos de identidade representam informações (declarações) fornecidas a um cliente para identificar um usuário. As declarações podem incluir o nome de usuário, o endereço de email e assim por diante.
Os clientes que estarão se conectando para solicitar tokens.
O mecanismo de armazenamento para informações do usuário, como ASP.NET Identidade Principal ou uma alternativa.
Ao especificar clientes e recursos para o IdentityServer4 usar, você pode passar uma IEnumerable<T> coleção do tipo apropriado para métodos que usam repositórios de clientes ou de recursos em memória. Ou para cenários mais complexos, você pode fornecer tipos de cliente ou provedor de recursos por meio da injeção de dependência.
Uma configuração de exemplo para IdentityServer4 para usar recursos na memória e clientes fornecidos por um tipo IClientStore personalizado pode ser semelhante ao exemplo a seguir:
// Program.cs
builder.Services.AddSingleton<IClientStore, CustomClientStore>();
builder.Services.AddIdentityServer()
.AddSigningCredential("CN=sts")
.AddInMemoryApiResources(MyApiResourceProvider.GetAllResources())
.AddAspNetIdentity<ApplicationUser>();
//...
Consumir tokens de segurança
A autenticação em um endpoint OpenID Connect ou a emissão de seus próprios tokens de segurança cobre alguns cenários. Mas e um serviço que simplesmente precisa limitar o acesso aos usuários que têm tokens de segurança válidos que foram fornecidos por um serviço diferente?
Para esse cenário, o middleware de autenticação que manipula tokens JWT está disponível no pacote Microsoft.AspNetCore.Authentication.JwtBearer . JWT significa "Token Web JSON" e é um formato de token de segurança comum (definido pelo RFC 7519) para comunicação de declarações de segurança. Um exemplo simplificado de como usar middleware para consumir esses tokens pode se parecer com esse fragmento de código, extraído do microsserviço Ordering.Api do eShopOnContainers.
// Program.cs
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
// Add Authentication services
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = identityUrl;
options.RequireHttpsMetadata = false;
options.Audience = "orders";
});
// Build the app
app.UseAuthentication();
//…
app.UseEndpoints(endpoints =>
{
//...
});
Os parâmetros neste uso são:
Audiencerepresenta o receptor do token de entrada ou o recurso ao qual o token concede acesso. Se o valor especificado nesse parâmetro não corresponder ao parâmetro no token, o token será rejeitado.Authorityé o endereço do servidor de autenticação emissor de token. O middleware de autenticação do portador JWT usa esse URI para obter a chave pública que pode ser usada para validar a assinatura do token. O middleware também confirma que oissparâmetro no token corresponde a esse URI.
Outro parâmetro, RequireHttpsMetadataé útil para fins de teste; defina esse parâmetro como false para que você possa testar em ambientes em que não tenha certificados. Em implantações do mundo real, os tokens de portador JWT sempre devem ser passados apenas por HTTPS.
Com esse middleware ativado, os tokens JWT são extraídos automaticamente dos cabeçalhos de autorização. Eles são então desserializados, validados (usando os valores nos parâmetros Audience e Authority) e armazenados como informações do usuário a serem referenciadas posteriormente por ações do MVC ou filtros de autorização.
O middleware de autenticação do portador JWT também pode dar suporte a cenários mais avançados, como usar um certificado local para validar um token se a autoridade não estiver disponível. Para esse cenário, você pode especificar um TokenValidationParameters objeto no JwtBearerOptions objeto.
Recursos adicionais
Compartilhando cookies entre aplicativos
https://learn.microsoft.com/aspnet/core/security/cookie-sharingIntrodução à Identidade
https://learn.microsoft.com/aspnet/core/security/authentication/identityAutenticação de dois fatores com SMS
https://learn.microsoft.com/aspnet/core/security/authentication/2faHabilitando a autenticação usando o Facebook, o Google e outros provedores externos
https://learn.microsoft.com/aspnet/core/security/authentication/social/Michell Anicas. Uma introdução ao OAuth 2
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2AspNet.Security.OAuth.Providers (repositório GitHub para provedores OAuth ASP.NET)
https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/tree/dev/srcIdentityServer4. Documentação oficial
https://identityserver4.readthedocs.io/en/latest/