¿Patrones empresariales para la autenticación JWT para aplicaciones basadas en REST?

9

La especificación JWT describe solo la carga útil y cómo se envía, pero deja abierto el protocolo de autenticación, lo que permite la flexibilidad, pero desafortunadamente, la flexibilidad puede conducir a antipatterns y mal diseño.

Estoy buscando un patrón empresarial bien pensado y probado para la autenticación JWT, que podría usar o adaptar, pero no pude encontrar algo completo.

Lo que estaba pensando es:

  • cuando no se cumple con el encabezado de autorización, o el token JWT no es válido o ha caducado, envíe HTTP 401
  • Para autenticar, use / inicie sesión en el canal REST, envíe el nombre de usuario y la contraseña como objeto JSON
  • Para mantener vivo el token, use el canal REST / keepalive, llámelo cada N (5) minutos, reciba un nuevo token JWT y reemplace el existente después de cada llamada (el token expira después de M (15) minutos)

Sin embargo, lo que me perturba es la necesidad de ese canal / keepalive. Por otro lado, me obliga a evitar que caduque la autenticación, incluso si el usuario está ausente (la decisión, si queremos que Keepalive aún no se cumpla) y, por supuesto, esas son llamadas adicionales y complicaciones adicionales al protocolo. Lo que sería interesante es que ese servidor prolonga automáticamente el token. En el entorno basado en la sesión, esto ocurre al restablecer la marca de tiempo, aquí, sin embargo, el servidor tendría que enviar un token nuevo, tal vez no cada vez, pero una vez que el token expire en R (digamos, 10) minutos. Pero colocarlo en el cuerpo de respuesta significaría modificar el protocolo de respuesta JSON (por lo tanto, la solución es invasiva y no transparente), y colocar un encabezado HTTP adicional que el cliente pueda procesar no necesariamente puede ser un buen patrón. YO'

¿Hay algún patrón empresarial listo que responda a mis puntos abiertos? ¿Es mi borrador de protocolo una idea confiable? Prefiero usar algo listo que diseñar desde cero.


fuente
1
Si. JWT ha llevado a muchas personas a implementar 'protocolos' de cosecha propia y descartar el código marco probado. Para obtener la solución correcta, será importante tener claros los requisitos. Parece que el vencimiento de la 'sesión' es un requisito. ¿Es obligatorio cerrar la sesión? es decir, donde alguien del lado del servidor puede decir, cierre la sesión de este usuario, o un usuario puede decir cerrar sesión en todas mis sesiones.
joshp

Respuestas:

4

JWT ( Introducción a JSON Web Token ) es solo un formato de token, la autenticación es algo completamente fuera de alcance para esa especificación. De hecho, se usa comúnmente dentro de los sistemas de autenticación, pero también podría usarlo para escenarios completamente diferentes, por lo que tiene sentido no incluir restricciones específicas de autenticación dentro de esa especificación.

Si está buscando orientación sobre la autenticación, debe consultar la familia de especificaciones OpenID Connect . Además, si su sistema está compuesto por API de HTTP y está interesado en proporcionar acceso delegado a esas API a su propia aplicación de cliente o de terceros, debe consultar la especificación OAuth 2.0 .

Existen protocolos adicionales relacionados con la autenticación como SAML y WS-Federation que todavía se usan ampliamente en escenarios empresariales, pero su implementación es significativamente más compleja.

Sobre sus puntos abiertos específicos:

  • El esquema de autenticación de token de portador se define en RFC 6750 que contiene instrucciones sobre cómo realizar solicitudes y los posibles códigos de error .
  • OAuth2 y OpenID Connect contemplan la posibilidad y definen la forma de intercambiar un nombre de usuario / contraseña con un token.
  • El problema de extender una vida útil de token autónomo / por valor (JWT) se aborda dentro de OpenID Connect y OAuth2 a través de los tokens de actualización .

Aunque OAuth2 y OpenID Connect pueden verse como más fáciles de implementar que algunos de sus predecesores, siguen siendo lo suficientemente complejos como para garantizar cierta precaución y solo implementarlos usted mismo si está dispuesto a gastar una cantidad considerable de tiempo y recursos. En general, es una mejor opción utilizar bibliotecas o servicios de terceros que hacen ese trabajo pesado por usted.

Finalmente, estos protocolos cubren muchos escenarios, por lo que pueden ser excesivos en algunas situaciones.

João Angelo
fuente
2
+1 por garantizar precaución y una respuesta completa a la pregunta implícita en lugar de la escrita.
Paul
3

No creo que necesites un canal keepalive. Su carga útil puede (y se recomienda) contener información de caducidad proporcionada por el servidor (en la expclave, según el estándar ) cuando el token se genera al iniciar sesión. Si se usa un token caducado (que, obviamente, lo determina el servidor, que solo confía en lo que está en el token si la firma se valida), el servidor simplemente lo rechaza con HTTP 401, lo que hace que el cliente vuelva a autenticarse.

Los clientes, mientras tanto, pueden ser proactivos. La sección de carga no está encriptada, y dado que el cliente puede leerla, el cliente puede determinar cuándo se enviará una solicitud con un token caducado y, por lo tanto, /loginvolver a llamar si el token ha caducado.

Alternativamente, REST permite que la información de hipermedia se envíe como 'un motor de estado', por lo que si lo desea, puede hacer que su JWT sea de un solo uso y también con una caducidad. Cada solicitud, entonces, generaría un nuevo JWT que se devuelve en la respuesta al cliente, ya sea en el contenido o más probablemente en un encabezado de respuesta, como lo hace hapi-auth-jwt2 .

Pablo
fuente