Estamos tratando de determinar la mejor manera de autorizar a los usuarios en una arquitectura de microservicio, al tiempo que garantizamos que los microservicios tengan permisos limitados. Nuestra arquitectura utiliza un servicio de autorización central para manejar la emisión de tokens JWT.
Tenemos los siguientes requisitos:
Los usuarios deben limitarse a realizar ciertos roles. por ejemplo, un usuario solo debe poder crear / modificar / leer el contenido que posee.
Los microservicios deben limitarse solo a los permisos que requieren. por ejemplo, un microservicio que solo necesita leer datos de otro servicio debe tener prohibido explícitamente escribir datos en ese servicio.
Como ejemplo, supongamos que tenemos un sistema donde los usuarios pueden subir imágenes a un servicio de almacenamiento de imágenes. Tenemos un servicio de etiquetado que etiqueta automáticamente las imágenes con una ubicación. Los usuarios solo pueden CRUDAR sus propias imágenes. El servicio de etiquetado puede leer cualquier imagen del servicio de almacenamiento de imágenes, sin embargo, no debe poder modificar / eliminar.
¿Cuál es una buena manera de lograr lo anterior usando tokens JWT? Algunas soluciones que hemos discutido son:
El servicio de almacenamiento de imágenes expone 2 API, una que está disponible externamente (brindando acceso CRUD al usuario) y otra que está disponible internamente (brinda acceso interno de solo lectura). Parece inflexible: ¿qué sucede si otro servicio interno necesita acceso de lectura / escritura a todas las imágenes (por ejemplo, una que elimina automáticamente imágenes explícitas)?
Configuramos dos permisos en el JWT del usuario, uno es CRUD_OwnImages y el otro es READ_ForAnalysis. El servicio de etiquetado puede ver si el usuario tiene permisos READ_ForAnalysis y, de ser así, realizar la solicitud correspondiente. Tenemos otro microservicio que verifica si el usuario tiene CRUD_OwnImages para operaciones CRUD en las propias imágenes del usuario. Esto pone la responsabilidad en cada microservicio para garantizar que el usuario esté restringido a las acciones que requiere. El almacén de imágenes no tiene forma de restringir cada microservicio con este enfoque, por lo que es potencialmente propenso a errores y fallas.
Le damos al microservicio de etiquetado su propio usuario, con READ_ForAnalysis como permiso. Luego, cuando el servicio de etiquetado solicita imágenes del almacén de imágenes, se le da acceso a ellas, pero está prohibido modificarlas. El usuario del usuario solo tiene el permiso CRUD_OwnImages, por lo que puede recuperar y acceder solo a sus imágenes desde la interfaz. Si otro servicio necesita CRUD para todos los datos, podemos darle CRUD_AllData o similar. Nos gusta este enfoque, ya que cada servicio ahora es responsable de sus propios datos (en lugar de que esa lógica se duplique en varios servicios), pero ¿qué sucede si el servicio requiere permisos de usuario y de microservicio? ¿Podemos enviar dos tokens JWT (tanto del usuario como del microservicio) de forma segura? ¿Hay alguna manera de combinar los permisos de forma segura y enviarlos? p.ej
El problema se exacerba si la información del usuario se necesita más abajo (a 2 o 3 microservicios de distancia). ¿Suponemos que depende de los microservicios individuales restringirse a las acciones que necesitan y no hacerlo explícito?
Respuestas:
En general, tantas operaciones como sea posible deberían estar vinculadas a un usuario humano real. Obliga a las personas a autenticarse adecuadamente, impulsa una estrategia de autorización única y consistente, y es una parte importante de proporcionar una pista de auditoría coherente.
Y en general, tiene tres tipos de escenarios con microservicios:
1. El usuario entra, sube una foto y necesita ser etiquetado. Excelente. El servicio de fotografía puede simplemente pasar el JWT al servicio de etiquetado (o viceversa, dependiendo de la dirección de su dependencia) y si el usuario no tiene derechos para realizar la suboperación, tome las medidas apropiadas (tal vez cargue la foto sin una etiqueta , tal vez devuelva el error, tal vez otra cosa).
2. El usuario entra, sube una foto y necesita ser etiquetado ... pero no ahora. Frio. Manejas la foto ahora como de costumbre. Más tarde, cuando se produce el etiquetado (manejo de eventos / mensajes, procesamiento de comandos de estilo CQRS, procesamiento de trabajos periódicos, lo que sea) el servicio de etiquetado se hará pasar por el usuario (muy probablemente mediante el uso de un secreto compartido para solicitar un JWT personalizado de la autenticación) y luego la suboperación en nombre del solicitante original (con todos sus permisos y limitaciones). Este método tiene el problema habitual con las operaciones asincrónicas en las que es difícil proporcionar errores al usuario si las cosas no salen bien, pero si está utilizando este patrón para operaciones de servicio cruzado, ya lo habría resuelto.
3. Algunos subsistemas necesitan hacer cosas fuera del contexto de un usuario. Quizás tengas algún trabajo nocturno para archivar imágenes antiguas. Tal vez sus etiquetas deban consolidarse ... En este caso, es probable que desee que cada uno de estos actores tenga su propio pseudousuario con permisos limitados y una identificación única para la pista de auditoría.
Cuál usar variará según su escenario, sus necesidades y su tolerancia al riesgo. Y, por supuesto, estos son solo un conjunto incompleto de generalizaciones generales de trazo.
Pero en general, los microservicios en sí mismos no deberían ser usuarios si es posible.
fuente