Flujo de inicio de sesión único mediante JWT para la autenticación entre dominios


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 lo que 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 sea autenticado en example2.com , automáticamente.

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

Así que ahora el usuario está de vuelta en example1.com y está autenticado! Puede hacer peticiones, pasando el token JWT en un encabezado Authentication y el servidor es capaz de verificar el JWT firmado y por lo tanto es capaz de identificar al usuario. ¡Bonito!

Primera cuestión :

¿Cómo debería el token JWT se almacenará en el cliente? Hay, una vez más, mucha información sobre esto, y la gente parece estar de acuerdo en que usar Web Storage es el camino a seguir en lugar del viejo cookies. 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 todavía se autenticará en example1.com , siempre y cuando el token JWT no haya caducado!

También, si example1.com necesita hacer una solicitud Ajax para otro de nuestros dominios, entiendo que configurar CORS permitiría eso. Pero nuestro caso de uso principal no son las solicitudes entre dominios, ¡es tener una solución de inicio de sesión único !

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, usando el token JWT que ya tiene? Local Storage no parece permitir el acceso entre dominios, por lo que en este punto el navegador no puede lea el token JWT para hacer solicitudes a example2.com !

Debería:

  • El usuario será redirigido al servidor de autenticación de nuevo? 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 y lo redirige inmediatamente a example2.com con el mismo token JWT?
  • O puede el navegador, en example2.com , acceder al token JWT sin tener que ir al servidor de autenticación de nuevo? Veo que hay soluciones de almacenamiento cruzado , pero ¿se usan ampliamente? ¿Son la solución sugerida para un entorno SSO de dominio cruzado?

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

Author: electrotype, 2015-11-15

3 answers

El usuario debe ser redirigido al servidor de autenticación de nuevo 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.

 15
Author: Hans Z.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-16 00:01:20

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 sistemas de inicio de sesión único que utilizan protocolos conocidos como oauth2 o OpenIdConnect

Sin embargo, cuando este esquema se usa entre dominios cruzados, el principal inconveniente de 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á al usuario como no autenticado.

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

  1. Para autenticar al usuario en example1.com, redireccionarlo al servidor de autenticación en sso.example.com, emitir un JWT después de autenticarse y almacenarlo en el localStorage de este dominio. Después de esto, redirige 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 padre recibe el mensaje y obtiene el token adjunto continuando con el flujo de SSO

No hay problema con la política del mismo origen porque sso.example.com tiene acceso a su localStorage y la comunicación entre iframe y la página principal está permitida si origen y destino reconocerse unos a otros (ver http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage )

Para simplificar el desarrollo, hemos lanzado recientemente un cross domain SSO 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 redirecciones y evitar inicios de sesión innecesarios cuando los dominios están federados

 14
Author: pedrofb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-29 21:31:34

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 simple proxy inverso resolvería su problema (al menos el almacenamiento entre dominios).

So example1.com example2.com

Se convertiría en algo como

Example.com/example1

Example.com/example2

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

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

Y si esa no es una opción, es posible que tenga que recurrir a nombre de usuario+pin, ya que los navegadores se están volviendo más estrictos sobre la interacción entre dominios.

 1
Author: Tezra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 15:56:49