.NET 7 - Autenticação e Autorização : novidades
Hoje vou apresentar as novidades do .NET 7.0 relacionadas com a autenticação e autorização. |
O lançamento do .NET 7 dá continuidade ao esforço de simplificação iniciado com o .NET 5 fornecendo alguns recursos relacionados à autenticação e autorização que facilitam um pouco a vida dos desenvolvedores .NET.
Vamos dar uma olhada rápida nesses recursos, que variam de simplificações na configuração de autenticação à adição de novas ferramentas de teste de autorização, a melhorias no suporte à autenticação do Blazor.
Esquema de autenticação padrão
Ao configurar a autenticação para sua aplicação, você precisa registrar o
serviço de autenticação por meio de AddAuthentication().
Por exemplo, o código a seguir é necessário para configurar o
JwtBearer como o esquema de autenticação em uma API
da Web ASP.NET Core:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}"; options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidAudience = builder.Configuration["Auth0:Audience"], ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}" }; }); |
Embora você esteja definindo apenas um esquema de autenticação (JwtBearerDefaults.AuthenticationScheme), o método AddAuthentication() requer que você especifique o esquema padrão a ser usado quando não for especificado em seus endpopints da API.
A partir do .NET 7, o esquema padrão não é mais necessário quando você define apenas um esquema de autenticação pois agora ele é inferido automaticamente pelo framework. Na prática, você pode escrever o código anterior da seguinte forma:
builder.Services.AddAuthentication() .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}"; options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidAudience = builder.Configuration["Auth0:Audience"], ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}" }; }); |
Caso precise restaurar o comportamento antigo por qualquer motivo, você pode desativar o novo recurso usando a seguinte instrução:
AppContext.SetSwitch("Microsoft.AspNetCore.Authentication.SuppressAutoDefaultScheme", true); |
Configuração Simplificada
Uma das críticas recorrentes à autenticação e autorização na plataforma .NET é
sua complexidade. Na verdade, o .NET fornece aos desenvolvedores um sistema
articulado para gerenciamento de autenticação e autorização. Este sistema é
ótimo pela flexibilidade que oferece, mas pode ser difícil para um iniciante
digerir todos os detalhes.
Para contornar esse problema a versão .NET 7 traz uma abordagem simplificada para configurar a autorização de APIs da Web ASP.NET Core com base em tokens de acesso no formato JWT.
Se você já protegeu uma API da Web ASP.NET Core com Auth0, o código a seguir deve parecer familiar para você:
using Microsoft.AspNetCore.Authentication.JwtBearer; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}"; options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidAudience = builder.Configuration["Auth0:Audience"], ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}" }; }); builder.Services.AddAuthorization(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); ... |
Agora, você pode confiar diretamente no sistema de configuração integrado para definir as opções de autorização de sua API da Web. Na verdade, além dos esquemas de autenticação padrão, o .NET 7 carrega automaticamente as opções para configurar o serviço de autenticação da nova seção Authentication do arquivo de configuração appsettings.json.
Com esta nova funcionalidade, o código mostrado anteriormente passa a ser o seguinte:
using
Microsoft.AspNetCore.Authentication.JwtBearer; var builder = WebApplication.CreateBuilder(args);//novo recurso builder.Services.AddAuthentication().AddJwtBearer(); builder.Services.AddAuthorization(); var app = builder.Build(); |
Todas as definições de configuração são movidas para o arquivo appsetting.json da seguinte maneira:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", //nova seção "Authentication": { "Schemes": { "Bearer": { "Authority": "https://YOUR_AUTH0_DOMAIN", "ValidAudiences": [ "YOUR_AUDIENCE" ], "ValidIssuer": "YOUR_AUTH0_DOMAIN" } } } } |
A nova seção Authentication mantém as definições
de configuração para qualquer esquema de autenticação suportado por seu
aplicativo, embora atualmente apenas o esquema JwtBearer
seja suportado.
Observe que agora você não precisa mais chamar
UseAuthentication() e UseAuthorization(). O framework cuida de adicionar
automaticamente o middleware necessário ao pipeline de solicitação.
Políticas de autorização para endpoints
específicos
A ASP.NET Core permite que você especifique políticas para tomar decisões de
autorização mais precisas com base no conteúdo do token de acesso ou em outros
critérios avançados. Normalmente, essas políticas são definidas globalmente no
nível do aplicativo e anexadas às definições de terminal às quais a política se
aplica.
Definir políticas globalmente é muito bom para reutilização. No entanto, às
vezes você pode precisar apenas de uma política específica para um endpoint.
Nesse caso, você pode especificar sua política diretamente na definição do
endpoint.
Veja a seguir um exemplo de como você pode usar esse novo recurso:
app.MapGet("/api/special-endpoint", () => "A special endpoint!") .RequireAuthorization(p => p.RequireClaim("scope", "api:special"));
|
A ferramenta user-jwts
Testar uma API da Web protegida por token pode ser complexo. Você pode
facilmente usar ferramentas como curl ou Postman,
mas precisa passar um token de acesso válido junto com sua solicitação HTTP.
Para obter um token de acesso válido, você geralmente precisa de um sistema de
gerenciamento de identidade e acesso e precisar gerar o token. Você precisa
configurar sua API com este sistema e fazer login fornecendo credenciais
válidas.
O .NET 7 traz uma nova ferramenta CLI - user-jwts
- que ajuda a simplificar o teste de API da Web protegido.
Esta ferramenta esta integrada ao .NET CLI e permite gerar tokens de acesso no formato JWT. A ferramenta é baseada na mesma infraestrutura do gerenciador de segredos e permite que seu aplicativo valide o token de acesso gerado. Basicamente, o seguinte comando permite gerar um novo token de acesso:
dotnet user-jwts create |
Você pode usar esse token com curl, Postman ou qualquer outro cliente HTTP
para fazer sua chamada para os endpoints protegidos de sua API da Web sem a
necessidade de registrar seu aplicativo com um sistema real de gerenciamento de
identidade e acesso.
Além do uso básico, a ferramenta user-jwts
permite que você personalize seu token de acesso especificando os escopos,
declarações personalizadas e outras propriedades para que você também possa
testar endpoints com políticas de acesso.
Requests de autenticação dinâmica no Blazor
WASM
O Blazor WebAssembly usa o pacote
Microsoft.AspNetCore.Components.WebAssembly.Authentication para manipular
a autenticação OpenID Connect. Este pacote permite
que você defina estaticamente no momento da inicialização como a autenticação
ocorrerá. No entanto, há cenários em que pode ser necessário autenticar usuários
em tempo de execução com uma configuração diferente. Por exemplo, você pode
precisar executar autenticação avançada ou pode querer que o usuário altere sua
conta.
No .NET 7, o Blazor WebAssembly dá suporte à
criação de solicitações de autenticação dinâmica usando a nova classe
InteractiveRequestOptions e o método
NavigateToLogin() do objeto NavigationManager.
O exemplo a seguir mostra o uso básico desses novos recursos:
|
A classe InteractiveRequestOptions também fornece uma maneira de adicionar parâmetros personalizados à solicitação de autenticação. Por exemplo, considere o parâmetro screen_hint de Auth0 que permite que você mostre o formulário de inscrição em vez do formulário de login padrão. Você pode enviar este parâmetro para Auth0 conforme mostrado abaixo:
InteractiveRequestOptions requestOptions =
new() { Interaction = InteractionType.SignIn, ReturnUrl = NavigationManager.Uri, }; requestOptions.TryAddAdditionalParameter("screen_hint", "signup"); NavigationManager.NavigateToLogin("authentication/login", requestOptions); |
Blazor WASM Authentication Diagnostics
Detectar problemas de autenticação não é fácil, especialmente se você estiver
executando um código WebAssembly, como acontece com os aplicativos
Blazor WebAssembly.
A versão .NET 7 tenta melhorar seu suporte para diagnóstico de autenticação introduzindo o nível de depuração para a biblioteca Microsoft.AspNetCore.Components.WebAssembly.Authentication. Depois de habilitar o log para Blazor WebAssembly, você pode adicionar a seguinte configuração no arquivo de configuração wwwroot/appsettings.json para obter informações detalhadas sobre o processo de autenticação:
"Logging":
{ "LogLevel": { "Microsoft.AspNetCore.Components.WebAssembly.Authentication": "Debug" } } |
Conclusão
Provavelmente, os novos recursos introduzidos pelo .NET 7 para mitigar a
complexidade do suporte à autenticação e autorização não mudarão drasticamente a
sua vida como desenvolvedor mas vão facilitar a realização das tarefas
relacionadas com estas operações.
E estamos conversados.
"Jesus dizia a todos: "Se alguém quiser acompanhar-me, negue-se a si mesmo,
tome diariamente a sua cruz e siga-me."
Lucas 9:23
Referências: