Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Sugestão
Este conteúdo é um trecho do eBook, .NET Microservices Architecture for Containerized .NET Applications, disponível no do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.
Há tantos aspetos sobre segurança em microsserviços e aplicações web que o tópico poderia facilmente levar vários livros como este. Portanto, nesta seção, vamos nos concentrar em autenticação, autorização e segredos de aplicativo.
Implementar autenticação em microsserviços .NET e aplicativos Web
Muitas vezes, é necessário que os 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ços, a autenticação normalmente é tratada centralmente. Se você estiver usando um API Gateway, o gateway é um bom lugar para autenticar, como mostra a Figura 9-1. Se você usar essa abordagem, certifique-se de que os microsserviços individuais não possam ser acessados diretamente (sem o API Gateway), 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 API Gateway
Quando o API Gateway 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 Ative 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 partilhadas entre 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 cookies.) Este 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, é manipulada por um token de segurança emitido por um microsserviço dedicado, compartilhado entre microsserviços.
Autenticar utilizando 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 . ASP.NET Identidade Principal armazena informações do usuário (incluindo informações de entrada, funções e declarações) em um armazenamento 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, armazenamentos personalizados ou outros pacotes de terceiros podem ser usados para armazenar informações de identidade no Armazenamento de Tabela do Azure, no CosmosDB ou em outros locais.
Sugestão
ASP.NET Core 2.1 e posterior fornece ASP.NET Core Identity como uma biblioteca de classes Razor, para que você não veja muito do código necessário em seu projeto, como era o caso das versões anteriores. Para obter detalhes sobre como personalizar o código de Identidade para atender às suas necessidades, consulte Identidade de Scaffold em projetos do ASP.NET Core.
O código a seguir é retirado do modelo de projeto MVC do ASP.NET Core Web Application com 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 Identidade Principal estiver configurada, você a habilitará adicionando o app.UseAuthentication() e endpoints.MapRazorPages() conforme mostrado no 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).
Autentique usuários usando o tipo SignInManager. Pode utilizar
signInManager.SignInAsyncpara iniciar sessão diretamente ousignInManager.PasswordSignInAsyncpara confirmar que a palavra-passe do utilizador está correta e, em seguida, iniciar sessão.Identifique um usuário com base nas informações armazenadas em um cookie (que é lido pelo middleware ASP.NET 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 suporta autenticação de dois fatores.
Para cenários de autenticação que usam 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 fornecedores externos
ASP.NET Core também suporta o uso de provedores de autenticação externos 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 como mencionado anteriormente, usando o app.UseAuthentication() método, você também precisa registrar o provedor externo em Program.cs como 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 => { ... });
//...
Os provedores de autenticação externos populares e seus pacotes NuGet associados são mostrados na tabela a seguir:
| Provedor | Embalagem |
|---|---|
| A Microsoft | Microsoft.AspNetCore.Authentication.MicrosoftAccount |
| Microsoft.AspNetCore.Authentication.Google | |
| Microsoft.AspNetCore.Authentication.Facebook | |
| Microsoft.AspNetCore.Authentication.Twitter |
Em todos os casos, você deve concluir um procedimento de registro de aplicativo que depende do fornecedor e que geralmente envolve:
- Obter uma ID de aplicativo cliente.
- Obtenção de uma chave secreta do aplicativo cliente.
- Configurando uma URL de redirecionamento, que é manipulada pelo middleware de autorização e pelo provedor registrado
- Opcionalmente, configurar um URL de saída para lidar corretamente com a saída num cenário de Single Sign-On (SSO).
Para obter detalhes sobre como configurar seu aplicativo para um provedor externo, consulte a Autenticação de provedor externo na documentação do ASP.NET Core).
Sugestão
Todos os detalhes são tratados pelo middleware de autorização e pelos serviços previamente mencionados. Portanto, basta escolher a opção de autenticação de Conta de Usuário Individual ao criar o projeto de aplicativo Web ASP.NET Core no Visual Studio, como mostra a 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 autenticação externa, ao criar um projeto de aplicativo Web no Visual Studio 2019.
Além dos provedores de autenticação externos listados anteriormente, estão disponíveis pacotes de terceiros que fornecem middleware para usar muito mais 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 autenticação
A autenticação com ASP.NET Identidade Principal (ou Identidade mais provedores de autenticação externos) funciona bem para muitos cenários de aplicativos Web nos quais o armazenamento de 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 persistência e transmissão de dados.
Por exemplo, em uma API Web principal do ASP.NET 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 da Web, você normalmente deseja usar a autenticação de token de portador. Esses tipos de aplicativos não funcionam com cookies, mas podem facilmente recuperar 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 suporta 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 estiverem armazenadas no Azure Ative Directory ou em outra solução de identidade que ofereça suporte ao OpenID Connect ou 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 autenticar no microsserviço Identity.Api no eShopOnContainers, um aplicativo Web ASP.NET Core pode usar middleware desse pacote, conforme mostrado no exemplo simplificado a seguir no 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 ASP.NET Core Identity não é necessário, porque todo o armazenamento e autenticação de informações do usuário são manipulados pelo serviço de Identidade.
Emitir tokens de segurança de um serviço ASP.NET Core
Se preferir emitir tokens de segurança para usuários locais do ASP.NET Core Identity em vez de usar um provedor de identidade externo, você pode aproveitar algumas boas bibliotecas de terceiros.
O IdentityServer4 e o OpenIddict são provedores do OpenID Connect que se integram facilmente ao ASP.NET Core Identity para permitir que você emita 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.
Você configura o IdentityServer4 no Program.cs fazendo uma chamada para o construtor. Services.AddIdentityServer.
Você chama app. UseIdentityServer em Program.cs para adicionar IdentityServer4 ao pipeline de processamento de solicitação HTTP do aplicativo. Isso permite que a biblioteca sirva 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 da API representam dados ou funcionalidades protegidos que um usuário pode acessar com um token de acesso. Um exemplo de um recurso de API seria uma API da Web (ou conjunto de APIs) que requer autorização.
Os recursos de identidade representam informações (declarações) que são fornecidas a um cliente para identificar um usuário. As declarações podem incluir o nome de usuário, endereço de e-mail e assim por diante.
Os clientes que estarão se conectando para solicitar tokens.
O mecanismo de armazenamento de informações do usuário, como ASP.NET Core Identity 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 recursos ou clientes na memória. Ou, para cenários mais complexos, 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 se parecer com o 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 num endpoint OpenID Connect ou a emissão dos seus próprios tokens de segurança cobre alguns cenários. Mas o que dizer de 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 "JSON Web Token" e é um formato de token de segurança comum (definido pela RFC 7519) para comunicar declarações de segurança. Um exemplo simplificado de como usar middleware para consumir esses tokens pode se parecer com este fragmento de código, retirado 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 recetor do token de entrada ou o recurso ao qual o token concede acesso. Se o valor especificado neste 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 tokens. 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, , é útil para fins de teste, RequireHttpsMetadatavocê define esse parâmetro como false para poder testar em ambientes onde não tem certificados. Em implantações do mundo real, os tokens de portador JWT sempre devem ser passados apenas por HTTPS.
Com esse middleware em vigor, 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 para serem referenciadas posteriormente por ações MVC ou filtros de autorização.
O middleware de autenticação do portador JWT também pode oferecer suporte a cenários mais avançados, como o uso de 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
Partilha de cookies entre aplicações
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/2faAtivando 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/