tutorial español authentication single-sign-on jwt openid-connect

authentication - español - Flujo de inicio de sesión único utilizando JWT para autenticación de dominio cruzado



openid connect tutorial (3)

Hay mucha información en la web sobre el uso de JWT ( Json Web Token ) para la autenticación. Pero todavía no encontré una explicación clara de cuál debería ser el flujo al usar tokens JWT para una solución de inicio de sesión único en un entorno de dominios múltiples .

Trabajo para una empresa que tiene muchos sitios en diferentes hosts. Usemos example1.com y example2.com . Necesitamos una solución de inicio de sesión único, lo que significa que si un usuario se autentica en example1.com , queremos que también se autentique en example2.com , automáticamente.

Usando el flujo de OpenId Connect , entiendo que el usuario que quiera autenticarse en example1.com primero será redirigido al servidor de autenticación (u OP : "Proveedor de OpenId"). El usuario se autentica en ese servidor que luego lo redirige al sitio original example1.com con un token JWT firmado. (Entiendo que hay otro flujo que devuelve un token intermedio que se puede intercambiar por el token JWT real más adelante, pero no creo que sea necesario para nosotros) ...

¡Así que ahora el usuario está de vuelta en example1.com y está autenticado! Puede realizar solicitudes, pasando el token JWT en un encabezado de Authentication y el servidor puede verificar el JWT firmado y, por lo tanto, puede identificar al usuario. ¡Agradable!

Primera pregunta :

¿Cómo se debe almacenar el token JWT en el cliente? Hay, de nuevo, mucha información sobre esto, y las personas parecen estar de acuerdo en que usar el Web Storage es el camino a seguir en lugar de las buenas cookies antiguas. Queremos que el JWT sea persistente entre los reinicios del navegador, así que usemos Local Storage , no Session Storage ...

¡Ahora el usuario puede reiniciar su navegador y seguirá siendo autenticado en example1.com , siempre que el token JWT no haya caducado!

Además, si example1.com necesita hacer una solicitud de Ajax a otro de nuestros dominios, entiendo que configurar CORS lo permitiría. Pero nuestro caso de uso principal no son las solicitudes de dominio cruzado, ¡tiene una única solución de inicio de sesión !

Por lo tanto, la pregunta principal:

Ahora, ¿cuál debería ser el flujo, si el usuario va a example2.com y queremos que se autentique, utilizando el token JWT que ya tiene? Local Storage no parece permitir el acceso entre dominios, por lo que en este momento el navegador no puede leer el token JWT para realizar solicitudes a example2.com !

Debería :

  • ¿El usuario será redirigido al servidor de autenticación nuevamente? Cuando el usuario se autenticó para example1.com , el servidor de autenticación puede haber establecido una cookie en el usuario, por lo que esta nueva solicitud de autenticación para example2.com podría usar esa cookie para ver que el usuario ya está autenticado e inmediatamente lo redirige a example2.com con el mismo token JWT?
  • ¿O puede el navegador, en example2.com , acceder al token JWT sin tener que volver al servidor de autenticación ? Veo que hay soluciones de almacenamiento cruzado , pero ¿son ampliamente utilizadas? ¿Son la solución sugerida para un entorno SSO de dominio cruzado?

No queremos nada lujoso, ¡estaríamos contentos con la solución más utilizada!


El usuario debe ser redirigido al servidor de autenticación nuevamente y obtener un nuevo token (JWT), uno que esté específicamente dirigido a example2.com. Así es como funciona OpenID Connect y cualquier otro protocolo SSO federado entre dominios.


No estoy seguro de si esto responde a su pregunta, pero si su objetivo principal es el inicio de sesión único, creo que un proxy inverso simple resolvería su problema (al menos el de almacenamiento entre dominios).

Así ejemplo1.com ejemplo2.com

se convertiría en algo así

ejemplo.com/ejemplo1

ejemplo.com/ejemplo2

(Y desde el lado del usuario, esto suele ser más limpio)

Si esa no es una opción, es posible que deba configurarlo para que cuando un usuario se autentique en 1 dominio, use AJAX / iframes ocultos para crear una autenticación con los otros dominios también (enviando un token de 1 hora a través de url si es necesario) )

y si ESA NO es una opción, es posible que deba recurrir al nombre de usuario + pin, ya que los navegadores se vuelven más estrictos sobre la interacción entre dominios.


Redirigir al usuario al servicio de autenticación central cuando el usuario no está registrado para solicitar credenciales y emitir un nuevo token de autenticación es el escenario común en los sistemas de inicio de sesión único que utilizan protocolos conocidos como oauth2 u OpenIdConnect

Sin embargo, cuando este esquema se usa entre dominios cruzados, el principal inconveniente es que el usuario se autenticará cada vez que navegue a otro dominio debido a la política del mismo origen : el token de sesión no se puede compartir entre dominios, por lo que el SSO tratará usuario como no autenticado.

example2.com no puede acceder a los datos de example1.com pero existe una técnica para compartir datos entre dominios usando el almacenamiento local / cookies del navegador y un iframe que apunta a un dominio intermedio sso.example.com

  1. Para autenticar al usuario en sso.example.com , sso.example.com servidor de autenticación en sso.example.com , emita un JWT después de autenticar y almacénelo en el almacenamiento local de este dominio. Después de esto, redirija al usuario al dominio de origen example1.com

  2. Cree un iframe en example2.com apuntando a sso.example.com . El iframe en sso.example.com lee el token JWT y envía un mensaje a la página principal

  3. La página principal recibe el mensaje y obtiene el token adjunto continuando con el flujo SSO

No hay ningún problema con la política del mismo origen porque sso.example.com tiene acceso a su LocalStorage y la comunicación entre el iframe y la página principal está permitida si el origen y el destino se reconocen entre sí (consulte http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage )

Para simplificar el desarrollo, recientemente lanzamos un SSO de dominio cruzado con JWT en https://github.com/Aralink/ssojwt

Este método es perfectamente compatible con los flujos SSO. Es solo una forma de compartir el token de autenticación sin redireccionamientos y evitar inicios de sesión innecesarios cuando los dominios están federados