Docker: Keycloak + MySQL — Auth OpenID Connect
Bom dia / boa tarde / boa noite
Nesse passo a passo vamos aprender a provisionar e configurar uma instancia do Keycloak utilizando o MySQL como banco de dados.
Iniciando o projeto
Para começar, vamos criar um novo diretório chamado docker-keycloak-mysql e vamos criar o arquivo docker-compose.yml que terá as informações dos nossos containers.
Para criar as imagens e provisionar os container, basta rodar o comando abaixo em qualquer terminal:
docker-compose up -d
O Keycloak
Keycloak é uma solução de gerenciamento de acesso e identidade de código aberto que facilita a proteção de aplicativos e serviços modernos com pouco ou nenhum código. O Keycloak vem com seus próprios adaptadores para plataformas selecionadas, mas também é possível usar bibliotecas genéricas de OpenID Connect.
Criando o Realm
Um Realm gerencia um conjunto de usuários, credenciais, roles e grupos. Um usuário pertence e efetua login em um realm. Os realms são isolados uns dos outros e só podem gerenciar e autenticar os usuários que controlam.
- Acesse o link e faça login no Keycloak Administrador Console utilizando as credenciais do KEYCLOAK_USER configurados no docker-compose.yml;
- No drop-down menu Master, clique em Add Realm. Quando você está conectado ao realm master, este drop-down menu lista todos os realms existentes.
- Digite Nodejs-Realm no campo Name e clique em Create.
Quando o realm é criado, a página principal do console admin é aberta. Observe que o realm atual agora está definido como Nodejs-Realm. Alterne entre o gerenciamento do Realm Master e o Realm que você acabou de criar clicando nas entradas no drop-down menu.
Certifique-se de que Nodejs-Realm esteja selecionado para as configurações abaixo. Evite usar o Realm Master. Você não precisa criar o realm o tempo todo. É um processo único.
Criando um Client
Os Clients são entidades que podem solicitar que o Keycloak autentique um usuário. Na maioria das vezes, os clients são aplicativos e serviços que desejam usar o Keycloak para se proteger e fornecer uma solução de single sign-on.
- Clique em Clients no menu lateral esquerdo. Todos os clients disponíveis para o Realm selecionado serão listados aqui.
2. Para criar um novo client, clique em Create. Você será solicitado a fornecer um Client ID, um Client Protocol e um Root URL. Uma boa escolha para o Client ID é o nome da nossa API (docker-nodejs-keycloak — será o nosso próximo artigo), o Client Protocol deve ser definido como openid-connect e o Root URL deve ser definida como a URL da API.
3. Depois de salvar, você verá a página de configuração do client, onde pode atribuir um Name e uma Description ao client, se desejar.
Defina o Access Type como confidential, Authorization Enabled como ON, Service Account Enabled como ON e clique em Save.
Na aba Credencial mostrará o Client Secret que é necessário para as configurações do Keycloak na aplicação do NodeJs.
4. Acesse a aba Client Roles para criar as definições de role do client docker-nodejs-keycloak. Imagine que a API que você está construindo tenha diferentes tipos de usuários com diferentes permissões de usuário. Ex: usuários e admins.
- Algumas APIs só podem ser acessadas por usuários.
- Algumas APIs só podem ser acessadas por admins.
- Algumas APIs podem ser acessadas por usuários e admins.
Conforme o exemplo, vamos criar duas roles: user e admin clicando no botão Add Role.
Criando Realm Roles
Os sistemas geralmente atribuem acesso e permissões a funções específicas, em vez de usuários individuais, pois lidar com usuários pode ser muito trabalhoso e difícil de gerenciar.
Vamos criar Realm Roles app-user e app-admin atribuindo as Roles do client docker-nodejs-keycloak correspondentes (user, admin).
- Clique na opção Roles no menu lateral esquerdo. Todas as roles disponíveis para o Realm selecionado serão listadas aqui.
2. Para criar a realm role app-user, clique em Add Role. Você será solicitado a informar um Role Name e uma Description. Preencha os detalhes e salve.
3. Depois de salvar, habilite Composite Roles e procure por docker-nodejs-keycloak no campo Client Roles. Selecione a role user do docker-nodejs-keycloak e clique em Add selected.
Esta configuração atribuirá a Client Role user à Realm Role app-user. Se você tiver vários clients com várias roles, escolha as roles necessárias de cada client para criar realm roles baseado em sua necessidade.
3. Siga as mesmas etapas para criar o Realm Role app-admin, mas atribua-o ao client role admin.
Criando Users
Users são entidades que podem fazer login em seu sistema. Eles podem ter atributos associados a si mesmos, como e-mail, username, etc. Eles podem ser atribuídos como membros do grupo e ter Roles específicas atribuídas a eles.
Vamos criar os usuários a seguir e atribuir as Roles app-user e app-admin à eles para fins de teste.
- user com app-user realm role;
- admin com app-admin realm role;
- sysadmin com app-user & app-admin realm roles;
- No menu, clique em Users para abrir a página da lista de usuários.
- No lado direito da lista de usuários, clique em Add User para abrir a página adicionar usuário.
- Insira um nome no campo Username; este é o único campo obrigatório. Mude o interruptor Email Verified de OFF para ON e clique em Save para salvar os dados e abrir a página de gerenciamento para o novo usuário.
4. Clique na aba Credentials para definir uma senha para o novo usuário.
5. Digite uma nova senha e confirme-a. Mude o interruptor Temporary de ON para OFF e clique em Set Password para definir a senha do usuário para a nova senha que você especificou. Para simplificar, vamos definir a senha como Mudar123 para todos os usuários.
6. Clique na aba Role Mappings para atribuir as realm roles ao usuário. A lista de realm roles estará disponível na lista de Available Roles. Selecione uma role e clique em Add Selected > para atribuí-la ao usuário.
Após a atribuição da role, as roles atribuídas estarão disponíveis na lista Assigned Roles. As atribuições de roles para user, admin e sysadmin seriam as seguintes.
Sim, foi um pouco complicado passar por todas as configurações. Mas quando você continuar usando o Keycloak, essas configurações se tornarão mais simples. Para que novos serviços sejam adicionados, você não precisa fazer todas as etapas acima. Você só precisa adicionar um novo Client com Client Roles e atribuir os clients roles às Realm Roles correspondentes.
Gerando os Tokens
Vamos aprender como gerar os tokens de acesso dos usuários do Keycloak.
- Vá para Realm Settings do Nodejs-Realm no menu lateral esquerdo e clique em OpenID Endpoint Configuration para visualizar os detalhes do OpenID Endpoint.
2. Copie token_endpoint do OpenID Endpoint Configuration. A URL será parecida com:
<KEYCLOAK_SERVER_URL>/auth/realms/<REALM_NAME>/protocol/openid-connect/tokenEx: http://localhost:3030/auth/realms/Nodejs-Realm/protocol/openid-connect/token
3. Use o seguinte comando CURL para gerar as credenciais de usuário. Substitua KEYCLOAK_SERVER_URL, REALM_NAME, CLIENT_ID, USERNAME, PASSWORD pelos valores corretos.
curl -X POST '<KEYCLOAK_SERVER_URL>/auth/realms/<REALM_NAME>/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=<CLIENT_ID>' \
--data-urlencode 'username=<USERNAME>' \
--data-urlencode 'password=<PASSWORD>'
Exemplo:
curl -X POST 'http://localhost:3030/auth/realms/Nodejs-Realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=docker-nodejs-keycloak' \
--data-urlencode 'client_secret=2d5cf1b4-c73d-4db6-9a4c-3057775313af' \
--data-urlencode 'username=user' \
--data-urlencode 'password=Mudar123'
Execute o CURL no Terminal ou use o Postman. A resposta ficaria assim como abaixo.
Vamos decodificar o token JWT access_token gerado para o user usando jwt.io.
O access_token inclui os detalhes da permissão.
- realm_access.roles inclui o app-user realm role.
- resource_access.docker-nodejs-keycloak.roles inclui o user client role.
- preferred_username inclui o username do usuário (user).
- iat, exp inclui o tempo de emissão do token, bem como o tempo de expiração do token. Os tempos de expiração do token de acesso podem ser personalizáveis em Realm Settings, na aba Tokens. Por default, o Access Token Lifespan é definido para 5 minutos, que pode ser personalizado com base em seus requisitos de segurança.
Na fase de teste do aplicativo NodeJs, vamos usar as etapas acima para gerar os tokens de acesso dos usuários. Além disso, se o token expirar, é possível gerar um novo token com o processo de refresh_token.
curl -X POST 'http://localhost:3030/auth/realms/Nodejs-Realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=docker-nodejs-keycloak' \
--data-urlencode 'client_secret=2d5cf1b4-c73d-4db6-9a4c-3057775313af' \
--data-urlencode 'refresh_token=xxxxxx.xxxxxxxxxx.xxxxxx'
NodeJs no próximo artigo…
Espero que tenham gostado e até a próxima!
Esse passo a passo foi inspirado no artigo do Dinuth De Zoysa, segue o link do artigo original.