Auth0 Client
1. Descripción general
auth0-client (Auth0 Client, según su pom.xml) es una librería JAR compartida que encapsula la integración con Auth0 para los microservicios de Hawkers. Envuelve la Management API de Auth0 (/api/v2/...) y el endpoint OAuth2 de obtención de token (/oauth/token) usando los clientes HTTP declarativos nativos de Spring (@HttpExchange + HttpServiceProxyFactory, Spring Framework 7), sin depender de Spring Cloud OpenFeign.
El proyecto no es un microservicio desplegable en el sentido tradicional: aunque contiene una clase @SpringBootApplication (Auth0ClientApplication), esta existe únicamente para dar soporte al arranque de tests/auto-configuración; su función real es la de auto-configuración de Spring Boot (@AutoConfiguration, registrada vía META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports) que se activa automáticamente en cualquier microservicio consumidor que declare la dependencia y las propiedades auth0.client.*.
Resuelve el problema de que cada microservicio que necesita interactuar con Auth0 (búsqueda de usuarios, alta de usuarios, gestión de roles) tenga que reimplementar la obtención y renovación del token de acceso (client_credentials) y el cliente HTTP correspondiente. Dentro del ecosistema Hawkers, actúa como capa de integración transversal para cualquier servicio que necesite gestionar identidades de usuario en Auth0 (por ejemplo, alta de clientes, asignación de roles de acceso).
2. Información técnica
| Propiedad | Valor |
|---|---|
artifactId | auth0-client |
groupId | com.hawkersco |
version | 1.0.25-SNAPSHOT |
| Java | 25 |
| Spring Boot | 4.0.6 (Spring Framework 7) |
| Tipo de artefacto | JAR (librería con auto-configuración Spring Boot; incluye clase @SpringBootApplication de soporte, sin despliegue independiente) |
| Módulos | Proyecto mono-módulo |
| Repositorio Maven | Google Artifact Registry — europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven |
3. Arquitectura y diseño
Paquetes principales
com.hawkersco.auth0client
├── client/ # Interfaces @HttpExchange (clientes HTTP declarativos)
├── config/ # @AutoConfiguration + @ConfigurationProperties
├── dto/ # Records inmutables para requests/responses de Auth0
└── Auth0ClientApplication.java # Clase @SpringBootApplication de soporte
Componentes clave
client/Auth0Client— interfaz@HttpExchangepara la Management API de Auth0 (/api/v2/): búsqueda de usuarios por email, creación de usuarios, listado de roles, asignación de rol a usuario.client/Auth0TokenClient— interfaz@HttpExchangepara el endpoint/oauth/token; de uso interno exclusivo deAuth0ClientConfigpara obtener el token de acceso.config/Auth0ClientConfig— clase@AutoConfiguration, condicionada a que existan las cuatro propiedadesauth0.client.{url,id,secret,audience}(@ConditionalOnProperty). Registra los beansAuth0TokenClientyAuth0ClientmedianteRestClient+HttpServiceProxyFactory.config/Auth0Properties—recordcon@ConfigurationProperties(prefix = "auth0.client"):url,id,secret,audience.config/Auth0TokenClientConfig— clase@Configurationvacía (sin beans definidos actualmente).dto/— DTOs modelados como Java Records inmutables, con anotaciones dobles Jackson (@JsonProperty) y Gson (@SerializedName) en varios campos.
Patrón de autenticación transparente
El bean Auth0Client se construye con un ClientHttpRequestInterceptor que, en cada petición saliente, invoca a Auth0TokenClient para obtener un token Bearer vía client_credentials y lo añade a la cabecera Authorization. El consumidor de la librería solo interactúa con Auth0Client; la gestión de tokens es transparente.
.requestInterceptor((request, body, execution) -> {
request.getHeaders().set("Authorization", BEARER_PREFIX + getAccessToken(properties, auth0TokenClient));
return execution.execute(request, body);
})
Nota de diseño: el token se solicita en cada petición saliente (no hay caché/reutilización del access_token entre llamadas), lo que implica una llamada adicional a /oauth/token por cada operación contra la Management API.
Flujo principal
sequenceDiagram
participant MS as Microservicio consumidor
participant AC as Auth0Client (proxy HttpExchange)
participant Interceptor as RequestInterceptor
participant ATC as Auth0TokenClient
participant Auth0 as Auth0 (tenant)
MS->>AC: getUsersByEmail(email) / createUser(...) / ...
AC->>Interceptor: antes de ejecutar la petición
Interceptor->>ATC: getToken(client_credentials, id, secret, audience)
ATC->>Auth0: POST /oauth/token
Auth0-->>ATC: access_token
Interceptor->>Interceptor: parsea access_token (Jackson)
Interceptor->>AC: añade header Authorization: Bearer <token>
AC->>Auth0: petición real (GET/POST /api/v2/...)
Auth0-->>AC: respuesta
AC-->>MS: ResponseEntity<...>
4. Dependencias principales
| Dependencia | Propósito |
|---|---|
org.springframework.boot:spring-boot-starter | Núcleo de Spring Boot (auto-configuración, contexto). |
org.springframework:spring-web | RestClient, HttpServiceProxyFactory y soporte @HttpExchange para los clientes HTTP declarativos. |
com.fasterxml.jackson.core:jackson-databind | Deserialización de la respuesta del endpoint /oauth/token y de los DTOs anotados con @JsonProperty. |
org.projectlombok:lombok (1.18.42) | @Slf4j en Auth0ClientConfig para logging. |
com.google.code.gson:gson (2.13.1) | Anotaciones @SerializedName presentes en los DTOs (uso dual junto a Jackson). |
org.springframework.boot:spring-boot-starter-test (test) | Soporte de test de Spring Boot. |
Extensión de build relevante: com.google.cloud.artifactregistry:artifactregistry-maven-wagon (2.2.1) — necesaria para publicar/resolver contra el Google Artifact Registry corporativo.
5. API / Endpoints
No expone API REST propia (no hay @RestController). En su lugar, define clientes HTTP declarativos que consumen la Management API de Auth0:
Auth0Client (/api/v2/... del tenant Auth0)
| Método HTTP | Ruta | Descripción | Request | Response |
|---|---|---|---|---|
| GET | /api/v2/users-by-email | Busca usuarios de Auth0 por email. | Query param email | List<Auth0UsersByEmailResponse> |
| POST | /api/v2/users | Crea un usuario en Auth0. | Auth0CreateUserRequest (JSON) | Auth0CreateUserResponse |
| GET | /api/v2/roles | Lista los roles definidos en el tenant Auth0. | — | List<Auth0GetRolesResponse> |
| POST | /api/v2/users/{userId}/roles | Asigna uno o varios roles a un usuario. | Path userId + AssignRoleToUserRequest | String (respuesta cruda de Auth0) |
Auth0TokenClient (uso interno)
| Método HTTP | Ruta | Descripción | Request | Response |
|---|---|---|---|---|
| POST | /oauth/token | Obtiene el token de acceso client_credentials. | Map<String,String> con grant_type, client_id, client_secret, audience | String (JSON con access_token) |
Ejemplo de respuesta Auth0CreateUserResponse (valores de ejemplo, no reales):
{
"user_id": "auth0|********",
"email": "usuario@ejemplo.com",
"email_verified": false,
"name": "Nombre Apellido",
"given_name": "Nombre",
"family_name": "Apellido",
"nickname": "nombre.apellido",
"picture": "https://.../picture.png",
"identities": [
{ "user_id": "********", "connection": "Username-Password-Authentication", "provider": "auth0", "isSocial": "false" }
],
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"blocked": false,
"user_metadata": {}
}
6. Integraciones externas
| Sistema | Protocolo / Mecanismo | Dirección del flujo |
|---|---|---|
| Auth0 (Management API + OAuth2 token endpoint) | HTTP/REST vía RestClient + @HttpExchange (application/json) | Saliente: el microservicio consumidor llama a Auth0 para buscar/crear usuarios, listar roles y obtener tokens. |
| Microservicios Hawkers consumidores | Dependencia Maven (com.hawkersco:auth0-client) + auto-configuración Spring Boot | Entrante como librería: se activa automáticamente al declarar la dependencia y configurar auth0.client.*. |
7. Configuración
El proyecto no incluye application.properties/application.yml propio de servicio (es una librería auto-configurable). Los microservicios consumidores deben declarar las siguientes propiedades para que Auth0ClientConfig se active (@ConditionalOnProperty exige las cuatro):
| Clave | Descripción | Ejemplo de valor |
|---|---|---|
auth0.client.url | URL base del tenant de Auth0. | https://${AUTH0_TENANT}.auth0.com |
auth0.client.id | Client ID de la aplicación M2M en Auth0. | ${AUTH0_CLIENT_ID} |
auth0.client.secret | Client Secret de la aplicación M2M en Auth0. | ${AUTH0_CLIENT_SECRET} |
auth0.client.audience | Audience de la API de Auth0 (Management API u otra). | ${AUTH0_AUDIENCE} |
Nunca deben commitearse valores reales de id, secret ni audience; se recomienda inyectarlos vía variables de entorno o gestor de secretos del entorno de despliegue.
8. Persistencia
No aplica. La librería no accede a ninguna base de datos; todo el estado relevante (usuarios, roles) reside en Auth0.
9. Procesos programados y mensajería
No aplica. No se han encontrado @Scheduled, @KafkaListener ni @RabbitListener en el proyecto.
10. Ejecución en local
Como librería auto-configurable, no se "ejecuta" de forma independiente en producción, aunque incluye una clase @SpringBootApplication (Auth0ClientApplication) que permite arrancar un contexto Spring Boot mínimo para pruebas locales de los beans de auto-configuración.
Requisitos previos: JDK 25, Maven (o el wrapper ./mvnw incluido).
Build e instalación en repositorio Maven local (omitiendo tests, como en CI):
./mvnw -B -DskipTests clean install
Build con tests:
./mvnw clean install
Ejecutar una clase o método de test concreto:
./mvnw test -Dtest=ClassName
./mvnw test -Dtest=ClassName#methodName
No aplica verificación vía Actuator/health al no ser un servicio desplegable de cara a producción. Los microservicios consumidores deben declarar com.hawkersco:auth0-client:<version> en su pom.xml y configurar las propiedades auth0.client.* descritas en la sección 7.
11. Despliegue
El despliegue consiste en la publicación del artefacto Maven al Google Artifact Registry corporativo (no hay despliegue de contenedor/servicio propio).
Pipeline Jenkins (Jenkinsfile, agente any, JDK25 + Maven3):
- Checkout del repositorio.
- Publish to Artifact Registry:
mvn deploy -DskipTests, publicando enartifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven(definido endistributionManagementdelpom.xml).
Job de Jenkins:
https://jenkins-pi.hawkersco.net/job/auth0-client/
Los microservicios consumidores deben actualizar la versión de la dependencia en su propio pom.xml y redesplegar tras cada publicación relevante.
12. Manejo de errores y logging
Auth0ClientConfig captura explícitamente RestClientResponseException al solicitar el token de acceso y JsonProcessingException al parsear la respuesta, registrando el error vía SLF4J (@Slf4j, Lombok) y devolviendo una cadena vacía ("") como token en caso de fallo — no se lanza excepción hacia el consumidor en ese caso concreto, lo que implica que una petición a Auth0Client continuará con Authorization: Bearer (token vacío) si la obtención del token falla.
No hay excepciones de negocio propias ni códigos de error definidos; las respuestas de error de la Management API de Auth0 se propagan como RestClientResponseException estándar de Spring en las llamadas de Auth0Client (no capturadas dentro de la librería, salvo en la obtención del token).
No se ha encontrado configuración de logging propia (logback.xml/log4j2.xml); el logging queda delegado a la configuración del microservicio que integra la librería.
13. Notas y consideraciones
- Sin caché de token de acceso:
getAccessToken(...)se invoca en cada petición saliente delAuth0Client, generando una llamada adicional a/oauth/tokenpor cada operación de negocio. Si el volumen de llamadas es alto, esto puede suponer una sobrecarga innecesaria sobre el endpoint de token de Auth0 (posible mejora: cachear el token hasta su expiración). - Fallo silencioso en la obtención de token: si
getAccessToken(...)falla (excepción de red o de parseo), el método devuelve""en lugar de propagar el error, por lo que la petición a Auth0 se realiza igualmente con un headerAuthorization: Bearervacío, resultando previsiblemente en un401/403de Auth0 en vez de un fallo explícito y más temprano. Auth0TokenClientConfigestá vacía: la clase@Configurationno declara ningún bean; su propósito actual no es evidente desde el código (Pendiente de verificar si es un resto de una refactorización o si tiene un uso futuro previsto).- DTOs con doble anotación Jackson/Gson: varios registros (
Auth0CreateUserRequest,Auth0CreateUserResponse) anotan los mismos campos con@JsonPropertyy@SerializedNamesimultáneamente, aunque la librería solo usaRestClient/Jackson en tiempo de ejecución — las anotaciones Gson no se usan actualmente dentro de este proyecto (posible uso previsto por proyectos consumidores que reutilicen estos DTOs con Gson). - DTOs como Java Records: a diferencia de otras librerías commons de Hawkers (que usan clases Lombok para las entidades), aquí todos los DTOs son
recordinmutables, tal y como indicaCLAUDE.md; cualquier DTO nuevo debe seguir este mismo patrón. assignRoleToUserdevuelveResponseEntity<String>: la Management API de Auth0 responde sin cuerpo (204) en esta operación; el tipoStringcomo respuesta no está tipado a ningún DTO específico (Pendiente de verificar si esto es intencional o una simplificación pendiente de mejorar).