Keycloak: Autenticación con Java Quarkus
Implementación de servicio de autenticación Keycloak con api rest en Java Quarkus
Las últimas versiones de Keycloak ya no utilizan WildFly como servidor y motor de distribución, ahora implementan un servidor de aplicaciones basado en Java Quarkus. Por tanto, hay algunos cambios en la instalación y configuración del servicio.
El siguiente archivo manifiesto contiene la especificación básica de servicio Keycloak. Define usuario administrador, un volumen en directorio local para persistencia (base de datos H2), puerto tcp y un comando de modo de operación. El modo de operación de desarrollo (comando 'start-dev') es útil en entornos de prueba y desarrollo porque permite http y es menos exigente en cuanto a requisitos de seguridad y resolución de nombres de hosts. Para entornos de produción se debe utilizar el modo de operación 'start'.
docker-compose.yml
version: '3'
services:
keycloak:
image: quay.io/keycloak/keycloak:18.0.2
container_name: keycloak
restart: unless-stopped
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin123
volumes:
- ./data:/opt/keycloak/data/
ports:
- 8080:8080
command:
- start-dev
Vamos a crear un realm de ejemplo ('corp'), junto a un cliente ('service'), usuarios ('lab', 'dev') y roles ('user', 'admin'). Esto lo haremos en el terminal, utilizando el servicio admin-cli disponible en el directorio /opt/keycloak/bin/ del contenedor.
Iniciar servicio Keycloak e ingresar a contenedor:
docker-compose run -d
docker exec -it keycloak bash
Acceder a directorio de binarios de administración de Keycloak y autenticarse con usuario 'admin' definido en docker compose:
cd opt/keycloak/bin/
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
Crear realm:
./kcadm.sh create realms -s realm=corp -s enabled=true -o
Crear cliente, asociarlo al nuevo realm, definir parámetros de acceso y url de servicio rest:
./kcadm.sh create clients -r corp -s clientId=service -s enabled=true
-s clientAuthenticatorType=client-secret -s secret=qwe1234.
-s publicClient=false -s bearerOnly=false -s standardFlowEnabled=true
-s directAccessGrantsEnabled=true -s serviceAccountsEnabled=true
-s "redirectUris=[\"http://localhost:8000/api/*\"]"
Crear usuarios y asociarlos al nuevo realm
./kcadm.sh create users -r corp -s username=lab -s enabled=true
./kcadm.sh set-password -r corp --username lab --new-password lab123
./kcadm.sh create users -r corp -s username=dev -s enabled=true
./kcadm.sh set-password -r corp --username dev --new-password dev123
Crear roles y asociarlos al realm y a los nuevos usuarios
./kcadm.sh create roles -r corp -s name=user
./kcadm.sh create roles -r corp -s name=admin
./kcadm.sh add-roles --uusername lab --rolename user -r corp
./kcadm.sh add-roles --uusername dev --rolename admin -r corp
Servicio Rest Java Quarkus
Dependencias en archivo pom.xml de proyecto Java Quarkus de ejemplo:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-keycloak-authorization</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
Archivo de propiedades de proyecto java, se define la url de servicio keycloak con el realm de ejemplo 'corp' y cliente 'service':
quarkus.http.port=8000
quarkus.oidc.auth-server-url=http://localhost:8080/realms/corp
quarkus.oidc.client-id=service
Clases con métodos para pruebas básicas de acceso a recursos protegidos utilizando la anotación @RolesAllowed:
AdminResource.java:
@Path("/api/admin")
public class AdminResource {
@GET
@Path("/info")
@RolesAllowed("admin")
@Produces(MediaType.TEXT_PLAIN)
public String user() {
return "admin resource granted..";
}
}
UserResouce.java, tiene un recurso público de ejemplo ('/api/users/open'):
@Path("/api/users")
public class UserResource {
@GET
@Path("/info")
@RolesAllowed("user")
@Produces(MediaType.TEXT_PLAIN)
public String user() {
return "user resource granted..";
}
@GET
@Path("/open")
@PermitAll
@Produces(MediaType.TEXT_PLAIN)
public String open() {
return "public resource..";
}
}
Pruebas con curl: autenticarse y obtener access token:
curl -X POST http://localhost:8080/realms/corp/protocol/openid-connect/token \
--user service:qwe1234. \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'username=lab&password=lab123&grant_type=password'
curl -X POST http://localhost:8080/realms/corp/protocol/openid-connect/token \
--user service:qwe1234. \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'username=dev&password=dev123&grant_type=password'
Probar servicio java quarkus con curl, utilizando access token:
curl -v -X GET \
http://localhost:8000/api/users/info \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia.."
curl -v -X GET \
http://localhost:8000/api/admin/info \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2l.."
Puedes descargar el código fuente completo de este ejemplo en el siguiente enlace.
¿Tienes alguna consulta?
Puedes contactarme enviándome un mensaje desde aquí.
diciembre 16, 2022 Backend
septiembre 19, 2022 Redes/Networking, Embedded Systems
julio 20, 2022 Cloud
- Backend(4)
- Redes/Networking(4)
- Embedded Systems(2)
- Cloud(2)
- Frontend(3)
- Microservicios(4)