Gestão centralizada de identidade e autenticação com Keycloak

Keycloak é uma solução de IAM – Identity and Access Management – de código aberto desenvolvida pela Red Hat, que a utilizou como base para seu produto Red Hat Single Sign-On. Ele atua como um provedor de identidade e permite centralizar a autenticação e autorização para aplicativos e sistemas em ambientes corporativos.

A centralização da autenticação e da identidade de acesso traz vantagens no aspecto de segurança. Autenticação em múltiplos fatores e requisitos de senha podem ser impostos e, para a suspensão de um acesso, basta fazê-lo em um só lugar, sendo mais rápido e sem a chance de um outro acesso ser esquecido e mantido ativo como pode acontecer quando a identidade é distribuída em diferentes sistemas.

Keycloak é distribuído de algumas formas, entre elas os famosos pacotes de arquivo ZIP e TAR, bem como contêiner Docker, o que facilita a implantação e manutenção em ambientes de produção. Mas como esse projeto teve o objetivo de entender como funciona a aplicação, o arquivo foi escolhido.

Para a execução do Keycloak, será criado um usuário de serviço dedicado.

# useradd -m -d /opt/keycloak -s /usr/sbin/nologin keycloak

Keycloak é uma aplicação em Java e atualmente a documentação recomenda o OpenJDK 25. Além disso, ele utiliza o PostgreSQL. As configurações suportadas podem ser verificadas no link:

Considerando um sistema RHEL 10.2:

# dnf install java-25-openjdk postgresql-server

Configure o PostgreSQL substituindo o tipo de autenticação ident em conexões do tipo host por scram-sha-256, que utiliza senha. O ident utiliza o usuário no sistema operacional para autenticar no servidor de banco de dados, de forma similar ao peer mas para conexões TCP em vez de socket unix. Para isso, seria necessário utilizar um serviço de ident.

# postgresql-setup --initdb
# sed -i 's/ident/scram-sha-256/g' /var/lib/pgsql/data/pg_hba.conf
# systemctl enable --now postgresql.service

Criando o banco de dados no PostgreSQL:

# sudo -u postgres psql
postgres=# CREATE ROLE keycloak_op WITH LOGIN PASSWORD 'key&peele';
postgres=# CREATE DATABASE keycloak_db OWNER keycloak_op TEMPLATE template0 ENCODING 'UTF8';

Então, podemos executar o shell como o usuário de serviço criado para baixar e configurar o Keycloak:

# sudo -u keycloak bash

$ wget -P /tmp https://github.com/keycloak/keycloak/releases/download/26.7.4/keycloak-26.7.4.tar.gz

$ tar -xzvf /tmp/keycloak-26.7.4.tar.gz -C /opt/keycloak --strip-components=1

$ chmod +x /opt/keycloak/bin/*

O Keycloak tem um arquivo de configuração em /opt/keycloak/conf/keycloak.conf, onde é necessário determinar os seguintes parâmetros:

db=postgres
db-username=keycloak_op
db-password=key&peele
db-url=jdbc:postgresql://localhost/keycloak_db
hostname=https://keycloak.exemplo.com

# Configuração para uso com o proxy reverso HTTP, desabilitando SSL
http-enabled=true
proxy-headers=xforwarded
proxy-trusted-addresses=192.168.1.10

O template da configuração também oferece os parâmetros de certificado e chave SSL. Por padrão, o Keycloak escuta nas portas 8080 para HTTP e 8443 para HTTPS. No entanto, com o https:// especificado no parametro hostname ele já entende que no proxy reverso o acesso será feito pela porta padrão 443.

O Keycloak é compilado utilizando um framework chamado Quarkus, que faz uma espécie de intermediação entre o Java e o Keycloak. Quando uma aplicação inicia, o Quarkus tem uma sequência de etapas de descoberta dos componentes da aplicação. Uma recomendação é otimizar esse processo do Quarkus com uma espécie de “snapshot” que ele faz dos componentes da aplicação a serem iniciados, o que permite o Keycloak iniciar mais rápido.

$ /opt/keycloak/bin/kc.sh build

Então a aplicação pode ser testada com essa otimização sendo executada como:

$ /opt/keycloak/bin/kc.sh start --optimized

O comando de otimização deve ser executado novamente após atualizações do Keycloak. Falta agora criar o administrador inicial da aplicação no banco de dados.

$ /opt/keycloak/bin/kc.sh bootstrap-admin user

De volta ao shell como administrador ou root, é necessário agora liberar a porta para HTTP no firewall.

# firewall-cmd --permanent --add-port=8080/tcp
# firewall-cmd --reload

Criando um arquivo para a unidade de serviço do systemd em /etc/systemd/system/keycloak.service:

[Unit]
Description=Keycloak IAM
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=keycloak
Group=keycloak
WorkingDirectory=/opt/keycloak

ExecStart=/opt/keycloak/bin/kc.sh start --optimized

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Então basta habilitar e iniciar o serviço com:

# systemctl enable --now keycloak.service

Após a instalação e a configuração do proxy reverso, o Keycloak pode ser acessado através da página web. O administrador criado através do comando de bootstrap é temporário, devendo se criar outro usuário administrador e excluir o usuário temporário. Para criar outro usuário administrador, deve-se estar no realm master (único criado por padrão na instalação).

Após criado, vá na aba de credenciais e adicione uma senha.

Então vá na aba “Role mapping” e adicione o papel de admin.

Após logar no novo usuário, exclua o usuário temporário.

Agora sobre a organização interna do Keycloak. Ele é dividido em realms, que são como domínios isolados. Cada realm tem seus usuários, grupos e configurações. O master, único realm existente por padrão após a instalação, é para gerenciamento do próprio Keycloak e não deve ser utilizado para criar usuários de aplicações. Em vez disso, outro realm deve ser criado.

Dentro desse novo realm pode-se criar um cliente, que é uma aplicação que irá utilizar o Keycloak como provedor de identidade. Vou utilizar o Nextcloud como exemplo por ser uma aplicação que tem suporte oficial a esse tipo de configuração. Podemos configurar o tipo de autenticação como OpenID Connect ou SAML. Seguindo com o exemplo utilizando OIDC:

A chave de autorização pode ser deixada desabilitada, porque a autorização é definida pelo servidor Nextcloud: ele determina qual usuário é administrador, qual usuário tem acesso a quais compartilhamentos de arquivos, etc.

A caixa “Standard Flow” determina o fluxo de autenticação padrão para navegadores web. Para fazer o login, o usuário é redirecionado para fazer login no Keycloak.

Alternativamente, existe a opção “Direct Access Grants”, em que o login é feito na página do Nextcloud, que envia as credenciais para o Keycloak.

“Standard Flow” é recomendado porque assim a senha do usuário fica restrita ao Keycloak, enquanto em “Direct Access Grants” a senha passa pela aplicação, o que em muitos casos é indesejado – como por exemplo quando o provedor do serviço e o cliente são organizações diferentes. Além disso, a ideia é sempre minimizar a exposição da senha. Assim, caso a aplicação seja comprometida não significa que a identidade do usuário também vai ser.

No Standard Flow, o fluxo de autenticação acontece da seguinte forma:

  1. Usuário acessa a página de login do Nextcloud.
  2. Nextcloud o redireciona à página de login do Keycloak.
  3. Usuário faz login no Keycloak.
  4. Keycloak gera um código de autorização e redireciona o usuário de volta ao Nextcloud enviando junto esse código de autorização, indicando que o usuário foi autenticado no Keycloak.
  5. Nextcloud faz uma chamada ao Keycloak, enviando as próprias credenciais de autenticação de cliente (quando habilitado) e devolvendo o código de autorização recebido e solicitando um token.
  6. Keycloak valida a autenticação do Nextcloud e o código de autorização e retorna o token para o Nextcloud.
  7. Nextcloud associa o token a uma sessão e estabelece a sessão do usuário.

Os passos 5 e 6 podem parecer redundantes após o 3 e 4 mas não são. Essa etapa a mais existe porque o código de autorização passa através de um redirect do Keycloak para o Nextcloud, passando pelo navegador web do usuário. O Nextcloud então no passo 5 faz uma chamada diretamente para o Keycloak, que valida o código de autorização e retorna ao Nextcloud um bearer token que o Nextcloud utiliza como credencial do usuário para estabelecer a sessão.

O “Implicit Flow” corta essa etapa e devolve ao navegador o token de acesso diretamente, o que agiliza o login mas agora o navegador possui o token.

As URLs de redirect são geradas pelo plugin de OIDC do Nextcloud após o registro do provedor de identidade, podem ser substituídas depois caso ainda não as tenha.

Após a criação do cliente, crie o segredo para autenticação da aplicação no Keycloak.

Agora, deve ser configurado OpenID Connect no Nextcloud. A começar pela instalação do plugin:

Nas configurações de administração, basta registrar um novo provedor:

O endpoint de descoberta é /realms/<nome do seu dominio>/.wellknown/openid-configuration.

Após essa configuração, o Nextcloud exibe a opção de login com o provedor configurado.

Ao clicar nesse botão, o usuário é levado à página de login do Keycloak.

Ao fazer o login, o Nextcloud cria o usuário e inicia a sessão.

Uma funcionalidade interessante do Keycloak é que ele pode também passar à aplicação os grupos aos quais o usuário pertence e, caso a aplicação tenha suporte, ela pode automaticamente provisionar os grupos e atribuir o usuário a eles.

Isso pode ser vantajoso quando recursos ou permissões na aplicação são concedidos a grupos em vez de contas individuais, de forma que o usuário pode ser criado já com os acessos desejados. No Nextcloud, por exemplo, um compartilhamento de arquivos pode ser feito para um grupo.

Para configurar isso no Keycloak, deve-se criar um mapeamento de grupos. Configurando apenas para um cliente específico, isso é feito nos detalhes do cliente, na aba “Client scopes”, no escopo dedicado do cliente, nextcloud-oidc-dedicated.

Basta adicionar um Mapper do tipo “Group Membership” com o nome que a aplicação espera no token. No caso do Nextcloud, o mapeamento foi configurado para groups. Desative a opção “Full group path” para evitar que o nome do grupo seja passado à aplicação como /nome-do-grupo.

No Nextcloud, o provedor de identidade precisa ter o provisionamento de grupos habilitado e o regex de whitelist especificado para os grupos desejados. Nesse caso, foi configurado para aceitar todos os grupos.

Feita essa configuração, podemos atribuir um grupo ao usuário existente no Keycloak, e verificar que, após novo login, o grupo também aparece automaticamente no Nextcloud.