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

112

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 múltiples dominios .

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.

Al usar el flujo de OpenId Connect , entiendo que el usuario que desee autenticarse en example1.com será redirigido primero al servidor de autenticación (o 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 esto 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 Authenticationencabezado 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, nuevamente, mucha información sobre esto, y la gente parece estar de acuerdo en que usar Web Storagees el camino a seguir en lugar de lo bueno 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 seguirá estando autenticado en example1.com , ¡siempre que el token JWT no esté vencido!

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

Por tanto, la pregunta principal:

Ahora bien, ¿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 Storageno parece permitir el acceso entre dominios, por lo que en este punto el navegador no puede leer el token JWT para realizar solicitudes a example2.com .

Debería :

  • ¿El usuario será redirigido nuevamente al servidor de autenticación ? Cuando el usuario se autenticó para example1.com , el servidor de autenticación puede haber configurado 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 existen soluciones de almacenamiento cruzado , pero ¿se utilizan ampliamente? ¿Son la solución sugerida para un entorno SSO entre dominios?

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

electrotipia
fuente

Respuestas:

28

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.

Hans Z.
fuente
15
Pero sin que el usuario tenga que volver a enviar las credenciales de autenticación (nombre de usuario / contraseña, por ejemplo) ya que es SSO, ¿verdad? Entonces, ¿cómo se hace? ¿Debería el servidor de autenticación establecer una cookie estándar en el usuario la primera vez, para que pueda autenticarlo automáticamente cuando este usuario regrese de un nuevo dominio?
electrotipo
7
Pero, ¿qué pasa si el usuario configura el navegador para bloquear todas las cookies?
Christiaan Westerbeek
1
Supongo que se debe colocar una advertencia sobre las cookies de que "el sitio puede no funcionar correctamente si su navegador bloquea las cookies"
AnBisw
el inicio de sesión único no implica necesariamente que el usuario tenga una sesión en curso rastreada por una cookie: su característica definitoria es que uno reutiliza las mismas credenciales contra el mismo proveedor de identidad para obtener acceso a diferentes aplicaciones de terceros, es decir, no se requieren cookies, simplemente reutilización de las mismas credenciales
Hans
35

Redirigir al usuario al servicio de autenticación central cuando el usuario no ha iniciado sesión 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 OpenId Connect

Sin embargo, cuando este esquema se usa en todos los dominios, el principal inconveniente es que el usuario será redirigido y autenticado cada vez que navegue a otro dominio debido a la política del mismo origen : el token de acceso no se puede compartir entre dominios ( example2.comno se puede acceder a los datos of example1.com), por lo que el dominio de destino tratará al usuario como no autenticado, redirigiéndolo al servicio SSO central.

Para evitar que el servicio de autenticación vuelva a solicitar las credenciales, es común tener una cookie de sesión (no un token de acceso), pero existe una técnica para compartir datos entre dominios utilizando localStorage / cookies del navegador y un iframe que apunta a un dominio intermedio sso.example.com

  1. Para autenticar al usuario en example1.com, redirigirlo 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, redirija al usuario al dominio de origen example1.com

  2. Cree un iframe example2.comapuntando 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 el token adjunto continúa con el flujo de SSO.

No hay ningún problema con la política del mismo origen porque sso.example.comtiene acceso a su almacenamiento local y la comunicación entre el iframe y la página principal está permitida si los dominios de origen y destino se reconocen entre sí (consulte http://blog.teamtreehouse.com/cross-domain- mensajería-con-mensaje-posterior )

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

Este método es perfectamente compatible con los flujos de 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

pedrofb
fuente
3
Aparte de que esta solución no se adhiere a un estándar, generalmente en SSO entre dominios, uno cruza los límites administrativos y, en ese caso, el uso del mismo JWT para ambos dominios abriría la posibilidad de que el propietario de una aplicación en un dominio se haga pasar por el usuario en el otro. dominio
Hans Z.30 de
6
Gracias @HansZ. De hecho, hemos implementado esta solución para tener una sola administración de múltiples dominios con docenas de aplicaciones y los mismos usuarios. La operación es similar al sistema de Google (relativamente hablando)
pedrofb
2

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).

Entonces 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 deba configurarlo para que cuando un usuario se autentica en 1 dominio, use AJAX / iframes ocultos para crear una autenticación con los otros dominios también (enviando un token de 1 vez a través de la URL si debe ).

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

Tezra
fuente