Profundización en la Autenticación en Microservicios
Zexuan Luo / Shirui Zhao
December 23, 2022
¿Qué es el Servicio de Autenticación?
La autenticación es el proceso de verificar la identidad de un usuario para otorgarle acceso y los permisos necesarios para utilizar el sistema. El servicio que proporciona esta función es el servicio de autenticación. En una aplicación de software monolítica tradicional, todo esto ocurre dentro de la misma aplicación, pero en una arquitectura de microservicios, el sistema está compuesto por múltiples servicios. Cada microservicio tiene sus propias tareas en dicha arquitectura, por lo que implementar el proceso de autorización y autenticación por separado para cada microservicio no funciona completamente.
Este artículo comparará la autenticación tradicional con la autenticación en microservicios. Además, demostrará los cambios en la autenticación provocados por los cambios en la arquitectura. Finalmente, analizaremos los diversos servicios de autenticación en la arquitectura de microservicios y sus pros y contras en sus implementaciones.
Servicio de Autenticación en la Arquitectura Tradicional
En los primeros días, cuando las empresas desarrollaban servicios, todas las funciones se implementaban en la misma aplicación. Llamamos a este modelo "monolítico" para distinguirlo de la arquitectura más moderna y predominante de "microservicios".
Una aplicación monolítica consiste en una única unidad indivisible. Por lo general, es desarrollada de forma independiente por diferentes líneas de negocio y se combina en el mismo entorno cuando se despliega. Todos estos componentes están estrechamente integrados para proporcionar todas las funcionalidades en una sola unidad. Esta unidad tiene todos los recursos necesarios. La ventaja de una aplicación monolítica es que es fácil de desplegar e iterar. Es adecuada para empresas más independientes con menos líneas de negocio.
A medida que los negocios desarrollados por las empresas se vuelven cada vez más complejos, nos damos cuenta de que los servicios únicos ya no pueden satisfacer las necesidades de iteración rápida en la vida real. Necesitamos dividir este sistema gigante y asegurarnos de que las llamadas entre las funciones existentes se puedan llevar a cabo normalmente. Para resolver este problema, surgió el ESB (Bus de Servicios Empresariales).
El "bus de servicios empresariales" es una tubería que conecta varios servicios empresariales. La existencia del ESB es integrar diferentes servicios con diferentes protocolos. El ESB proporciona servicios como la traducción y el enrutamiento de solicitudes de clientes, para que diferentes servicios puedan interconectarse fácilmente. Como se puede deducir por su nombre, su concepto se inspira en el modelo de comunicación en el principio de composición de computadoras: el bus. Todos los sistemas que necesitan comunicarse con sistemas externos se conectan al ESB. Puedes usar el sistema existente para construir un nuevo sistema distribuido heterogéneo y débilmente acoplado.
El ESB ha traducido y enrutado las solicitudes para que diferentes servicios puedan comunicarse entre sí. El método tradicional de invocación de servicios en el ESB es que cada vez que el llamador debe ser enrutado primero a través del ESB central hacia el servicio.
Arquitectura Monolítica
La autenticación de usuarios y la gestión de sesiones son relativamente simples: la autenticación y la autorización ocurren en la misma aplicación, generalmente utilizando un esquema de autenticación basado en sesiones. Una vez autenticado, se crea una sesión y se almacena en el servidor. Cualquier componente puede acceder y usarla para notificar y autorizar solicitudes posteriores. El ID de sesión se envía al cliente y se utiliza para asociar todas las solicitudes posteriores con la sesión actual.
Arquitectura ESB
Bajo la arquitectura ESB, todos los procesos entre servicios se gestionan a través del bus ESB. Dado que la arquitectura ESB deriva de la arquitectura monolítica, el método de autenticación no ha cambiado en comparación con la arquitectura monolítica.
Servicio de Autenticación en la Arquitectura de Microservicios
Migrar de una arquitectura monolítica a una arquitectura de microservicios tiene muchas ventajas. Sin embargo, como una arquitectura distribuida, la arquitectura de microservicios tiene una superficie de ataque más grande, lo que hace que sea más difícil compartir el contexto del usuario. Por lo tanto, se necesitan diferentes servicios de autenticación en la arquitectura de microservicios para responder a desafíos de seguridad más significativos.
Podemos dividir los servicios de autenticación en la arquitectura de microservicios en las siguientes tres categorías:
- Implementar la autenticación en cada microservicio
- Implementar la autenticación a través de un servicio de autenticación
- Implementar la autenticación a través de la puerta de enlace API
Cada enfoque tiene sus propias ventajas y desventajas específicas.
Implementar la Autenticación en Cada Microservicio
Dado que cada microservicio se divide de la arquitectura monolítica, una transición natural para implementar la autenticación es que cada microservicio la implemente por su cuenta.
Cada microservicio debe implementar sus propias garantías de seguridad, aplicadas en cada punto de entrada. Este enfoque permite a los equipos de microservicios tomar decisiones autónomas sobre la implementación de sus soluciones de seguridad. Sin embargo, este enfoque tiene varias desventajas:
- La lógica de seguridad debe implementarse repetidamente en cada microservicio. Esto conduce a la duplicación de código entre servicios.
- Distrae al equipo de desarrollo de centrarse en su servicio principal.
- Cada microservicio depende de datos de autenticación de usuarios que no posee.
- Difícil de mantener y monitorear.
Una opción para mejorar esta solución es utilizar una biblioteca de autenticación compartida cargada en cada microservicio. Esto evitará la duplicación de código, y el equipo de desarrollo se centrará únicamente en su dominio de negocio. Sin embargo, todavía hay deficiencias que esta mejora no puede resolver. Debido a que la biblioteca de autenticación compartida aún necesita tener los datos de identidad del usuario correspondientes, también es necesario asegurarse de que cada microservicio utilice la misma versión de la biblioteca de autenticación. La biblioteca de autenticación compartida es más bien el resultado de una mala división de servicios.
Ventajas: implementación rápida, fuerte independencia
Desventajas: duplicación de código entre servicios; violación del principio de responsabilidad única; dificultad en el mantenimiento
Implementar la Autenticación a Través de un Servicio de Autenticación
Dado que es difícil que cada microservicio implemente la autenticación por sí mismo, y usar una biblioteca de autenticación compartida viola la intención original de la división de microservicios, ¿se puede mejorar la biblioteca de autenticación compartida a un servicio de autenticación dedicado?
En este caso, todo el acceso es controlado por el mismo servicio, similar a la función de autenticación en una aplicación monolítica. Cada servicio de negocio debe enviar una solicitud de autorización separada al módulo de control de acceso al realizar una operación.
Sin embargo, este enfoque ralentiza el servicio y aumenta la interconexión entre servicios. Y cada microservicio dependerá de este servicio de autenticación "único". Es vulnerable a un punto único de fallo y a una reacción en cadena que cause daños adicionales.
Ventajas: Cada microservicio tiene una única responsabilidad, y la autenticación está centralizada
Desventajas: Punto único de fallo; aumento de la latencia de las solicitudes
Implementar la Autenticación a Través de la Puerta de Enlace API
Al migrar a una arquitectura de microservicios, una pregunta que debe responderse es cómo se comunican los microservicios entre sí. El ESB mencionado anteriormente es un enfoque, pero más comúnmente, se emplea una puerta de enlace API. La puerta de enlace API es un punto de entrada único para todas las solicitudes. Proporciona flexibilidad al actuar como una interfaz central para consumir estos microservicios. Un microservicio que necesita acceder a otros microservicios (a partir de ahora, lo llamaremos "cliente" para distinguirlo del microservicio al que accede) no tiene acceso directo a los servicios, sino que envía la solicitud a la puerta de enlace API responsable de enrutar al cliente al servicio ascendente.
Debido a que todas las solicitudes deben pasar primero por la puerta de enlace API, es un excelente candidato para hacer cumplir problemas de autenticación. Reduce la latencia (llamadas a servicios de autenticación) y asegura que el proceso de autenticación sea consistente en toda la aplicación.
Por ejemplo, usando el plugin jwt-auth de APISIX, podemos implementar la autenticación en la puerta de enlace.
- Debemos configurar varias informaciones de identidad de usuario (nombre, clave, etc.) en APISIX.
- Según la clave del usuario proporcionada, iniciar una solicitud de firma a APISIX para obtener el token JWT del usuario.
- Luego, cuando el cliente necesita acceder a un servicio ascendente, lleva el token JWT, y APISIX actúa como la puerta de enlace API para intermediar este acceso.
- Finalmente, APISIX completará la operación de autenticación utilizando el token JWT.
Por supuesto, todo tiene ventajas y desventajas, y ninguna tecnología está exenta de inconvenientes. Usar una puerta de enlace API para completar la autenticación todavía tiene algunos problemas. Resolver este problema en la puerta de enlace es menos seguro que completar la autenticación dentro de cada microservicio. Por ejemplo, si la puerta de enlace API se ve comprometida, expondrá todos los microservicios detrás de ella. Pero el riesgo es relativo. En comparación con el servicio de autenticación único, el problema de usar una puerta de enlace API es leve.
Ventajas: Protección efectiva de los microservicios backend; los microservicios no necesitan manejar ninguna lógica de autenticación
Desventaja: Punto único de fallo
Resumen
En diferentes escenarios, necesitaremos diferentes esquemas de autenticación. En una aplicación monolítica, la autenticación ocurre dentro de la misma aplicación, y el servidor guarda todas las sesiones. En la era de los microservicios, las aplicaciones monolíticas han evolucionado a servicios distribuidos, y los métodos tradicionales de autenticación no son aplicables. En la arquitectura de microservicios, tenemos tres métodos de autenticación para elegir:
- Implementar la autenticación en cada microservicio
- Implementar la autenticación a través de un servicio de autenticación
- Implementar la autenticación a través de la puerta de enlace API
Cada opción tiene sus propias ventajas y desventajas, que deben analizarse en detalle según las circunstancias.