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
-
Para autenticar al usuario en
sso.example.com
,sso.example.com
servidor de autenticación ensso.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 -
Cree un iframe en
example2.com
apuntando asso.example.com
. El iframe en sso.example.com lee el token JWT y envía un mensaje a la página principal -
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