TL;DR

Saiba como usar o Keycloak no ASP.NET Core 6 usando Keycloak.AuthServices.Authentication.

Código fonte: https://github.com/NikiforovAll/keycloak-authorization-services-dotnet/blob/main/samples/AuthGettingStarted/Program.cs

Introdução ao Keycloak

Keycloak - Gerenciamento de Identidade e Acesso de Código Aberto. Adicione autenticação a aplicativos e serviços seguros com o mínimo de esforço. Não há necessidade de lidar com o armazenamento de usuários ou autenticação de usuários. O Keycloak fornece federação de usuários, autenticação forte, gerenciamento de usuários, autorização refinada e muito mais.

Pessoalmente, sou um grande fã do Keycloak porque é um sistema de gerenciamento de identidade e acesso maduro e completo. Ele contém tudo o que você pode precisar para a maioria dos cenários. Ao contrário do IdentityServer, é fácil de usar pronto para uso, sem necessidade de código para fazer as coisas funcionarem. Se o Azure Active Directory não for uma opção por algum motivo, eu definitivamente considero o Keycloak como uma opção de código aberto viável que poderia ser instalada no prem.

Caraterísticas:

  • Logon único
  • Corretagem de Identidade e Login Social
  • Federação de Usuários
  • Console de administração
  • Console de Gerenciamento de Contas
  • Serviços de Autorização

Veja: https://www.keycloak.org/

Ideias por trás do Keycloak.AuthServices.Authentication

Keycloak é OAuth2 + OpenID Connect provedor compatível, por isso deve ser fácil de usá-lo. Embora, leva algum tempo para que os conceitos e a configuração do Keycloak possam ASP.NET modelo de configuração da Autenticação Principal. Foi assim que preparei uma biblioteca de conveniência para acelerar o processo de integração e tornar o uso do Keycloak no mundo .NET mais agradável.

Basicamente, usamos para registrar e configurar o esquema de autenticação e fornecer .AddKeycloakAuthenticationJwtBearerDefaults.AuthenticationSchemeKeycloakAuthenticationOptions

/// <summary>
/// Adds keycloak authentication services.
/// </summary>
public static AuthenticationBuilder AddKeycloakAuthentication(
    this IServiceCollection services,
    KeycloakAuthenticationOptions keycloakOptions,
    Action<JwtBearerOptions>? configureOptions = default) {/*...*/}

image

A estrutura geral do projeto tem esta aparência:

var builder = WebApplication.CreateBuilder(args);

var services = builder.Services;
services.AddKeycloakAuthentication(authenticationOptions);

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", (ClaimsPrincipal user) =>
{
    app.Logger.LogInformation(user.Identity.Name);
}).RequireAuthorization();

app.Run();

Configurar KeycloakAuthenticationOptions

As são várias maneiras de configurar a autenticação Keycloak. Mais tarde, mostrarei como usar o adaptador de cliente Keycloak OIDC perfeitamente.

1️⃣ Construir objeto

var authenticationOptions = new KeycloakAuthenticationOptions
{
    AuthServerUrl = "http://localhost:8088/",
    Realm = "Test",
    Resource = "test-client",
};

services.AddKeycloakAuthentication(authenticationOptions);

2️⃣ Ler manualmente a partir da configuração

var configuration = builder.Configuration;
var authenticationOptions = configuration
    .GetSection(KeycloakAuthenticationOptions.Section)
    .Get<KeycloakAuthenticationOptions>();

services.AddKeycloakAuthentication(authenticationOptions);

3️⃣ A partir da configuração

var configuration = builder.Configuration;

services.AddKeycloakAuthentication(configuration, KeycloakAuthenticationOptions.Section);
// section is optional KeycloakAuthenticationOptions.Section = "Keycloak"
services.AddKeycloakAuthentication(configuration);

4️⃣ A partir do arquivo de configuração

keycloak.json usado pelo adaptador de cliente Keycloak OIDC para configurar clientes. Você também pode querer ajustar este arquivo depois de baixá-lo.

var configuration = builder.Configuration;
var host = builder.Host;
host.ConfigureKeycloakConfigurationSource("keycloak.json"); // file name is optional

services.AddKeycloakAuthentication(configuration);

Demo

Antes de começarmos a integrar, precisamos executar uma instância do Keycloak em uma máquina de desenvolvimento.

Consulte https://www.keycloak.org/getting-started/getting-started-docker para obter mais detalhes.

Vamos criar nosso primeiro reino.

  • Abra o Keycloak Admin Console
  • Passe o mouse sobre a lista suspensa no canto superior esquerdo, onde diz Mestre, e clique em Adicionar reino
  • Preencha o formulário com os seguintes valores:
    • Nome: Teste
  • Clique Create

add-realm

Criar um usuário

Inicialmente, não há usuários em um novo território, então vamos criar um:

  • Abra o Keycloak Admin Console
  • Clique (menu à esquerda)Users
  • Clique (canto superior direito da tabela)Add user
  • Preencha o formulário com os seguintes valores:
    • Nome do usuário: test@test.com
    • Primeiro Nome: Seu primeiro nome
    • Sobrenome: Seu sobrenome
  • Clique Save

usuário adicional

Vamos tentar garantir nossa primeira aplicação. O primeiro passo é registrar este aplicativo com sua instância Keycloak:

  • Abra o Keycloak Admin Console
  • Clique (menu à esquerda)Clients
  • Preencha o formulário com os seguintes valores:
    • Tipo de cliente: “OpenID Connect”
    • ID do cliente: test-client
  • Clique Save

add-cliente

Como mencionado acima, Keycloak tem um conceito de configuração do adaptador. Ele nos permite copiar configurações essenciais. é deliberadamente projetado para agilizar o processo de instalação, de modo que o imita a estrutura da configuração do adaptador.Keycloak.AuthServices.AuthenticationKeycloakAuthenticationOptions

Navegue pelo cliente recém-criado (canto superior direito) e clique em “Ação>Baixar configuração do adaptador”

adaptador-config

Aqui está o que parece:

{
  "realm": "Test",
  "auth-server-url": "http://localhost:8080/",
  "ssl-required": "external",
  "resource": "test-client",
  "public-client": true,
  "verify-token-audience": true,
  "use-resource-role-mappings": true,
  "confidential-port": 0
}

💡 Geralmente, você deseja usar o mapeador de protocolo para configurar o público necessário (“recurso” na configuração acima). Para simplificar a demonstração, podemos simplesmente desativar a validação de público. Alterar “verify-token-audience”: false. Consulte https://dbp-demo.tugraz.at/handbook/relay/keycloak/keycloak_audience/ e https://stackoverflow.com/a/53627747/8168625 para obter mais detalhes.

💡 Os tokens devem ser trocados com base em HTTPS, mas para o ambiente do desenvolvedor, você pode usar HTTP. Alterar “ssl-required”: “nenhum”

Agora, podemos criar keycloak.json ou estender appsettings.json.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Keycloak": {
    "realm": "Test",
    "auth-server-url": "http://localhost:8080/",
    "ssl-required": "none",
    "resource": "test-client",
    "verify-token-audience": false
    "confidential-port": 0
  }
}

Para usar a configuração fornecida, basta se registrar AddKeycloakAuthentication

var builder = WebApplication.CreateBuilder(args);

var services = builder.Services;
var configuration = builder.Configuration;
var host = builder.Host;

host.ConfigureLogger();
services.AddEndpointsApiExplorer().AddSwagger();

services.AddKeycloakAuthentication(configuration);
var app = builder.Build();

appv.UseSwagger().UseSwaggerUI();

app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", (ClaimsPrincipal user) =>
{
    app.Logger.LogInformation(user.Identity.Name);
}).RequireAuthorization();

app.Run();

Agora precisamos obter um token de acesso e fazer uma chamada via swagger-ui. Existem várias maneiras de fazê-lo. No meu caso, abri o “cliente de teste” e o tornei confidencial, e habilitei “Concessões de acesso direto”. Desta forma, podemos usar um nome de usuário e senha. Certifique-se de entender como configurar o OAuth 2.0 e o OpenId Connect antes de passar para a produção. No meu caso, é fácil de demonstrar.

cliente confidencial

curl --data "grant_type=password&client_id=test-client&username=test&password=test&client_secret=Tgx4lvbyhho7oNFmiIupDRVA8ioQY7PW" \
    localhost:8080/realms/Test/protocol/openid-connect/token

get-access-token

Now, we can navigate swagger and make an authentication request by providing an access token.[https://localhost:5001/swagger](https://localhost:5001/swagger)

swagger-ok

Vamos ver como podemos usar para criar políticas básicas com reconhecimento de Keycloak. Consulte: AuthorizationPolicyKeycloak.AuthServices.Authorization

💡 Keycloak tem um conceito de papéis. Adicionei funções de domínio e recursos nos bastidores. Sugiro que você descubra por conta própria como um exercício 😛.

No exemplo abaixo, exigimos que um usuário tenha a função de realm “admin” e a função de recurso “r-admin” usando e respectivamente. Observe que as funções de recurso são mapeadas automaticamente para funções, portanto, é igual ao .RequireRealmRolesRequireResourceRolesMicrosoft.AspNetCore.Authorizationb.RequireResourceRoles("r-admin")b.RequireRole("r-admin")

⚠ O de é usado como uma Audiência e como a chave para o mapeamento de função.resourceKeycloakAuthenticationOptions


var builder = WebApplication.CreateBuilder(args);

var services = builder.Services;
var configuration = builder.Configuration;
var host = builder.Host;

host.ConfigureLogger();

services.AddEndpointsApiExplorer().AddSwagger();

services.AddKeycloakAuthentication(configuration);
services.AddAuthorization(o => o.AddPolicy("IsAdmin", b =>
{
    b.RequireRealmRoles("admin");
    b.RequireResourceRoles("r-admin"); // stands for "resource admin"
    // resource roles are mapped to ASP.NET Core Identity roles
    b.RequireRole("r-admin"); 
}));
services.AddKeycloakAuthorization(configuration);

var app = builder.Build();

app.UseSwagger().UseSwaggerUI();
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", (ClaimsPrincipal user) =>
{
    app.Logger.LogInformation(user.Identity.Name);
}).RequireAuthorization("IsAdmin");

app.Run();

Aqui está a aparência dos logs após uma solicitação HTTP GET “/” bem-sucedida.

terminal-ok

Resumo

Você pode usar Keycloak.AuthServices para integrar com Keycloak. Keycloak tem toneladas de grandes recursos e, felizmente, podemos nos beneficiar do mundo de código aberto Java como desenvolvedores .NET.


Artigo Original