Ejemplo de integración de Plataforma en un microservicio
Introducción
Este microservicio funciona a modo de demostrador de integración con el Identity Manager, API Manager y logs centralizados.
La integración de seguridad del Identity Manager está basado en el protocolo OAuth2, que asegura el acceso a los diferentes puntos del microservicio a través de la autenticación en Plataforma.
El API Manager permite su publicación en Plataforma como API externa para poder acceder a la misma desde cualquier punto y de forma segura.
Los logs centralizados permiten almacenar las trazas del servicio para su posterior consulta en el Graylog de Plataforma, un espacio optimizado para el almacenamiento y consulta de logs.
Descripción del servicio
Template de microservicio
Para el desarrollo de este servicio se ha empleado al soporte al desarrollo de microservicios incluido en Plataforma (MSA Support).
A la hora de crear el microservicio elegiremos el Java 17 Microservice Template, que ofrece un esqueleto básico de un proyecto creado con Spring Boot.
Identity Manager
Este módulo se encarga de mostrar diferentes interfaces para la autenticación y autorización de los usuarios desde las aplicaciones de la plataforma. De esta forma, al ingresar en la URL del microservicio, se desplegará una pantalla de inicio de sesión similar a la de Plataforma.
La seguridad contra Keycloak permite gestionar la autenticación y autorización de usuarios mediante un servidor de identidad centralizado. Keycloak implementa los estándares OAuth2 y OpenID Connect, proporcionando un flujo de autenticación seguro que redirige a los usuarios a la pantalla de inicio de sesión de Keycloak. Una vez autenticados, los usuarios reciben un token JWT que contiene su identidad y roles, permitiendo que la aplicación valide su autenticidad y determine los permisos de acceso.
Todos los enlaces están protegidos mediante este mecanismo, con excepción de la ruta /api-docs, que sigue siendo pública para la publicación del esquema de la API. La integración con Keycloak asegura que solo los usuarios autorizados pueden acceder a los recursos protegidos, mientras que la validación de tokens JWT garantiza que las solicitudes sean seguras y estén autenticadas correctamente.
Para la configuración de este módulo es necesario asegurarse de que las dependencias de OAuth2 y JWT están incluidas en el proyecto. Esto permitirá que la aplicación se comunique con Keycloak y se habilite el soporte de OAuth2 para manejar flujos de autenticación y validar tokens JWT. Además, la configuración para integrar Keycloak se realiza principalmente en el archivo de configuración de la aplicación a través de diferentes valores clave como Authorization URI y Token URI.
Dentro del paquete que incluye todas las clases y archivos para la configuración del Identity Manager, destaca sobre todas SecurityConfig.java. En esta clase se encuentra el bean filterChain del tipo SecurityFilterChain, donde se gestiona el acceso a las diferentes rutas. Aquí también se configura la validación de tokens JWT y los flujos de login con Keycloak mediante OAuth2.
También es importante mencionar las funciones de BearerExtractorFilter.java, UserInfoServices.java y KeycloakAuthoritiesExtractor.java. Por un lado, el BearerExtractorFilter implementa un filtro personalizado para extraer el token Bearer de las solicitudes HTTP y autenticar a los usuarios. Este filtro se añade a la cadena de seguridad configurada en SecurityConfig.java y es clave para la validación de tokens JWT en las llamadas a la API.
Por otro lado, UserInfoServices.java es la clase encargada de realizar las peticiones al endpoint de información de usuario de Keycloak, para obtener los atributos del usuario autenticado. Esta información es utilizada para otorgar los roles y autoridades dentro del sistema, necesarios para determinar los permisos de acceso.
Por último, la clase KeycloakAuthoritiesExtractor.java se encarga de mapear los roles del usuario obtenidos desde Keycloak a las autoridades de Spring Security. De este modo, facilita el proceso de asignación de permisos a nivel de aplicación basados en los roles definidos en el servidor de identidad.
Para más información sobre la configuración del Identity Manager a nivel de código, se recomienda visitar esta guía: Integración con Identity Manager de Plataforma vía OAuth2/OpenID | Integración con el Flujo de autorización del IM en aplicaciones
API REST de publicación de indicadores
Este ofrece una interfaz REST Open API con una serie de operaciones que detallaremos a continuación.
La API expone 6 indicadores SXX a través de métodos GET, cada uno asociado a un modelo DTO que organiza y estructura los datos que se devuelven. Estos métodos no requieren parámetros de entrada, y cada uno de ellos devuelve una instancia del objeto que el KPI analiza.
Para cada uno de los indicadores, se ha creado un modelo DTO específico, cuyas propiedades incluyen tanto campos fijos (como el tipo de KPI, área, ID, etc.) como un campo variable, generalmente el kpiValue, que es el que contiene los datos reales que se están midiendo. A continuación, se describe cada uno de los modelos planteados y sus propósitos:
GestoresPIDPorDestinoDTO (KPI001): Este modelo representa el número de usuarios con el rol PID desglosado por destino. El campo kpiValue contiene una lista de destinos y el número de usuarios PID en cada uno.
AccesosPorDestinoYComponenteDTO (KPI002): Este modelo devuelve el número de accesos de usuarios desglosado por destino y componente. El campo kpiValue incluye destinos como "Benidorm", "Madrid", o "Barcelona", y dentro de cada destino se detalla el número de accesos por componente.
ConsultasPorDestinoDTO (KPI003): Muestra el número de consultas realizadas por destino, organizadas por componente. KpiValue incluye una lista de destinos y para cada destino, el número de consultas desglosado por componente (como "C1" o "C4").
UsuariosActivosDTO (KPI004): Este modelo mide el número de usuarios únicos que están utilizando la plataforma en un momento determinado. El valor en el campo kpiValue es simplemente un número que representa la cantidad de usuarios activos.
DestinosPorServicioDTO (KPI005): Representa el número de destinos habilitados por cada servicio. En el campo kpiValue, se devuelve una lista de servicios (como "S01" o "S02") y el número de destinos habilitados para cada uno.
UsuariosCiudadanosActivosDTO (KPI006): Este modelo mide cuántos usuarios ciudadanos están utilizando la plataforma en un momento determinado. El campo kpiValue contiene el número total de usuarios ciudadanos activos en la plataforma.
Por tanto, los endpoints para poder acceder a los diferentes métodos son los siguientes:
/api/c1/apikpis/v1/KPI001: Devuelve un ejemplo del número de usuarios con el rol PID por cada destino.
/api/c1/apikpis/v1/KPI002: Devuelve el número de accesos de usuario por destino y componente.
/api/c1/apikpis/v1/KPI003: Devuelve el número de consultas por destino.
/api/c1/apikpis/v1/KPI004: Mide cuántos usuarios únicos están usando la plataforma.
/api/c1/apikpis/v1/KPI005: Devuelve el número de destinos habilitados por servicio.
/api/c1/apikpis/v1/KPI006: Mide cuántos usuarios ciudadanos están usando la plataforma.
Por otro lado, ofrece otro endpoint /api/whoami para consultar la información del usuario logeado, que devuelve los atributos del token JWT.
Logs centralizados
Todos los logs generados por el microservicio son redirigidos y almacenados en el Graylog de Plataforma. Graylog es una solución de código abierto para la gestión centralizada de registros. Entre sus principales características, ofrece sistemas para la captura estándar de logs, así como herramientas para su organización y análisis en tiempo real.
Dentro de Graylog, en la pestaña de Streams, se encuentran categorizados los diferentes logs en función del módulo al que pertenecen. Para consultar los logs de este microservicio habrá que buscarlo por el nombre “SpringBoot Indicators Template Microservice”.
Para configurar un Stream por primera vez, desde la propia pestaña de Streams, hacemos click en el botón verde de “Create Stream”.
A continuación rellenamos el formulario con el título y descripción convenientes. El apartado Index Set debe permanecer como “Default index set”.
Una vez creado, lo buscamos a través de la barra de búsqueda para añadirle una regla, a través de la cual el Stream almacenará los logs que sigan dicha regla. En este caso, el Stream acogerá toda información cuyo campo “app_name” coincida con “SpringBootIndicatorsTemplate”.
Tras guardar los cambios, solo faltaría hacer click en el botón de “Start Stream” para que empiece a almacenar todos los logs de nuestro microservicio.
Para la configuración de Graylog dentro del microservicio, es necesario añadir una dependencia para poder crear appenders que soporten GELF. GELF (Graylog Extended Log Format) es un formato de mensajes diseñado específicamente para enviar logs estructurados a través de redes a un servidor de centralización de logs, como Graylog. A diferencia de los logs tradicionales en formato de texto plano, GELF utiliza un formato JSON enriquecido, lo que permite agregar campos personalizados (como es el caso de “app_name”).
Además, del mismo modo que el Identity Manager, gran parte de la configuración se administra en el archivo de configuración de la aplicación, definiendo propiedades y variables de entorno para el host y puerto de Graylog, por ejemplo.
Pero el archivo más importante sería el fichero logback-spring.xml, donde se crean y configuran todos los appender GELF, componente clave para la conexión contra Graylog y donde se indica el “app_name” que previamente habíamos establecido en las reglas del Stream. Un appender GELF es un componente utilizado en frameworks de logging, como Logback o Log4j, para enviar mensajes de log en el formato GELF a servidores de recolección de logs.
Para más información sobre la configuración de los Logs Centralizados a nivel de código, se recomienda visitar esta guía: Cómo crear un microservicio que escriba a la herramienta de Logs Centralizados
Consumo de API REST
El API de indicadores ha sido publicada en el API Manager de plataforma como API externa para integrar la seguridad de Plataforma en el microservicio.
Para publicar APIs externas, pulsamos en el botón “+” desde el API Manager para crear una API nueva.
En el formulario de creación indicaremos que el tipo de api es “Publish External REST API from Swagger JSON”. A continuación, cargaremos el esquema a través de la URL en el panel derecho de Operations. La forma de acceder a este esquema JSON en nuestro ejemplo es a través de la ruta /api-docs.
En las opciones inferiores, es necesario marcar las casillas “Publish to Gravitee” y “Enable JWT Security”. Si habilitamos la seguridad JWT, tendremos que elegir los Client ID (Realms de plataforma) que van a tener permisos de consulta sobre esa API. Para nuestro ejemplo, hemos elegido el realm de onesaitplatform.
Una vez creada, buscamos nuestra API con la ayuda de la barra de búsqueda, y dentro de las opciones disponibles, hacemos click en “Swagger” para poder visualizar y probar nuestra API externa ya securizada.
Para poder probar los métodos, previamente hay que ingresar el bearer token en el formulario que se nos muestra al clicar en el botón “Authorize”.