Tutorial: Integrar Quarkus com Keycloak

Objetivo
Integrar Quarkus com Keycloak para autenticação e autorização por papéis em endpoints REST. Inclui um caminho rápido com Dev Services e um setup “real” com Keycloak em Docker.
Pré‑requisitos
- Java 17+ e Maven ou Gradle
- Docker instalado
- Quarkus CLI opcional
Opção 1 — O caminho mais rápido (Quarkus Dev Services para Keycloak)
- Criar o projeto com OIDC e Segurança:
quarkus create app com.example:quarkus-keycloak -x=oidc,security,jackson-resteasy-reactive
cd quarkus-keycloak
- Configurar properties (dev):
# Perfil de desenvolvimento e Dev Services
quarkus.devservices.enabled=true
quarkus.keycloak.devservices.enabled=true
quarkus.keycloak.devservices.realm-name=quarkus
# API REST com Bearer token
quarkus.oidc.application-type=service
# Exigir autenticação por padrão
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
- Criar um recurso protegido (src/main/java/com/example/GreetingResource.java:
package com.example;
import jakarta.annotation.security.RolesAllowed;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("/hello")
public class GreetingResource {
@GET
@Path("/user")
@RolesAllowed({"user"})
public Response helloUser() {
return Response.ok("Olá, user!").build();
}
@GET
@Path("/admin")
@RolesAllowed({"admin"})
public Response helloAdmin() {
return Response.ok("Olá, admin!").build();
}
}
- Rodar a aplicação:
quarkus dev
O Quarkus iniciará um Keycloak de desenvolvimento automaticamente. Abra a Dev UI http://localhost:8080/q/dev para inspecionar OIDC e obter tokens de exemplo.
- Testar com token (substitua pelo JWT obtido):
TOKEN="<seu_token_jwt>"
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello/user
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello/admin
Opção 2 — Setup “real” com Keycloak (Docker) + Quarkus
1) Subir o Keycloak
docker run -d --name keycloak \
-p 8081:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.0 start-dev
- Console de Admin: http://localhost:8081
- Login: admin / admin
2) Configurar Realm, Client, Papéis e Usuários
No Console de Admin:
- Realm: quarkus
- Client (OpenID Connect):
- Client ID: quarkus-api
- Access type: “Bearer‑only” para API REST
- Se for web app: “Confidential” e configurar Redirect URIs
- Papéis (realm roles): user, admin
- Usuários:
- alice com papel user
- bob com papel admin
Observação: Papéis realm-level aparecem em realm_access.roles do token.
3) Configurar o Quarkus (OIDC)
Adicionar extensões (se precisar):
quarkus extension add oidc security jackson-resteasy-reactive
application.properties:
# OIDC apontando para o Keycloak externo
quarkus.oidc.auth-server-url=http://localhost:8081/realms/quarkus
quarkus.oidc.client-id=quarkus-api
# Se o client for confidential (web-app), informe o secret:
# quarkus.oidc.credentials.secret=<CLIENT_SECRET>
# Tipo de app
quarkus.oidc.application-type=service
# Autorização por padrão
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
# CORS (se necessário)
quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:3000,http://localhost:5173
quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
quarkus.http.cors.headers=Authorization,Content-Type
Recurso protegido: igual ao da Opção 1.
4) Obter token do Keycloak e testar
Fluxo Resource Owner Password (apenas para testes locais):
export KC_TOKEN_URL="http://localhost:8081/realms/quarkus/protocol/openid-connect/token"
curl -X POST "$KC_TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=quarkus-api" \
-d "grant_type=password" \
-d "username=alice" \
-d "password=<senha-da-alice>"
Copie access_token e teste:
TOKEN="<access_token>"
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello/user
Para admin, gere token do usuário bob e chame /hello/admin.
Quarkus como Web App (login via navegador)
- No Keycloak, client “Confidential” e Redirect URIs, por exemplo:
- application.properties (web app):
quarkus.oidc.application-type=web-app
quarkus.oidc.auth-server-url=http://localhost:8081/realms/quarkus
quarkus.oidc.client-id=quarkus-web
quarkus.oidc.credentials.secret=<CLIENT_SECRET>
# Áreas públicas x protegidas
quarkus.http.auth.permission.public.paths=/, /public/*
quarkus.http.auth.permission.public.policy=permit
quarkus.http.auth.permission.protected.paths=/app/*
quarkus.http.auth.permission.protected.policy=authenticated
Acessar /app redireciona para login no Keycloak.
Boas práticas de produção
- HTTPS entre app e Keycloak
- Ajustar TTL de tokens e refresh tokens
- Confiar no cache de JWKS do Quarkus OIDC
- Configurar proxy e
X-Forwarded-*quando aplicável - Restringir CORS aos domínios necessários
- Monitorar 401/403 e métricas de latência
Solução de problemas
- 401 Unauthorized
- Verificar header Authorization com Bearer
- Validade do token e relógio do sistema
- URL de auth-server correta
- 403 Forbidden
- Token sem papel esperado para
@RolesAllowed - Conferir
realm_access.rolesno token
- Token sem papel esperado para
- CORS
- Ajustar
origins,methodseheaders
- Ajustar
- Tipo de client
- API REST:
application-type=servicee clientbearer-only - Web app:
application-type=web-appe clientconfidentialcom secret
- API REST:
Resumo rápido
- Comandos essenciais:
# Keycloak
docker run -d --name keycloak -p 8081:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.0 start-dev
# Projeto Quarkus
quarkus create app com.example:quarkus-keycloak -x=oidc,security
quarkus dev
- Snippet de configuração (API):
quarkus.oidc.auth-server-url=http://localhost:8081/realms/quarkus
quarkus.oidc.client-id=quarkus-api
quarkus.oidc.application-type=service
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.cors=true
- Snippet de recurso:
@GET @Path("/user") @RolesAllowed({"user"})
@GET @Path("/admin") @RolesAllowed({"admin"})
🔐 Antes de levar para produção
- ❌ Nunca usar Dev Services em prod
- ❌ Nunca confiar só no Keycloak
- ✅ Validar iss, aud, exp
- ✅ HTTPS obrigatório
- ✅ Roles granulares
- ✅ Default deny
Anti-patterns (evite isso)
- ❌ Token em localStorage sem proteção
- ❌ CORS aberto
- ❌ Roles genéricas
- ❌ Sem validação de audience
- ❌ HTTP em produção
- ❌ Confiar só no Keycloak
Observabilidade e auditoria
Produção sem log de segurança = sistema cego.
Adicione:
- logs de autenticação
- logs de falha de autorização
- correlação de request (trace-id)
Conclusão
Integrar Quarkus com Keycloak não é apenas uma escolha técnica, mas sim uma decisão arquitetural que eleva o nível de segurança e maturidade da aplicação. Ao externalizar autenticação e autorização para um provedor especializado, você reduz a complexidade do código e ganha flexibilidade para evoluir regras de acesso sem precisar redeployar a aplicação.
Com o suporte a padrões como OAuth2 e OpenID Connect, essa integração se encaixa perfeitamente em cenários modernos de APIs e microsserviços, garantindo interoperabilidade e consistência entre diferentes sistemas.
Além disso, com o Keycloak rodando sobre Quarkus, você se beneficia de um stack mais leve, rápido e cloud-native, preparado para ambientes containerizados e escaláveis.
O ganho vai além da segurança: você constrói uma base sólida, desacoplada e pronta para crescer e exatamente o tipo de arquitetura que sustenta aplicações modernas em produção.
Publicado por: Guilherme Gomes - 02/05/2026 20:29
Caramelo.dev