Il existe beaucoup d’informations sur le Web concernant l’utilisation de JWT (Json Web Token
) pour l'authentification. Mais je n'ai toujours pas trouvé d'explication claire de ce que devrait être le flux lors de l'utilisation de jetons JWT pour une solution de connexion unique dans un environnement à plusieurs domaines.
Je travaille pour une entreprise qui a beaucoup de sites sur différents hôtes. Utilisons example1.com et example2.com . Nous avons besoin d’une solution d’authentification unique, ce qui signifie que si un utilisateur s’authentifie sur example1.com , nous voulons qu’il soit également authentifié sur example2.com , automatiquement.
En utilisant le flux OpenId Connect , je comprends que l'utilisateur qui souhaite s'authentifier sur example1.com sera d'abord redirigé vers le serveur d'authentification (ou OP
: "Fournisseur OpenId"). L'utilisateur s'authentifie sur ce serveur, qui le redirige ensuite vers le site d'origine example1.com avec un jeton JWT signé. (Je comprends qu'il existe un autre flux qui renvoie un jeton intermédiaire qui peut lui-même être échangé contre le véritable jeton JWT ultérieurement, mais je ne pense pas que cela soit nécessaire pour nous) ...
Alors maintenant, l'utilisateur est de retour sur example1.com et est authentifié! Il peut faire des demandes en passant le jeton JWT dans un en-tête Authentication
et le serveur est en mesure de vérifier le JWT signé et donc d'identifier l'utilisateur. Agréable!
Première question:
Comment le jeton JWT doit-il être stocké sur le client? Là encore, il y a beaucoup d'informations à ce sujet, et les gens semblent s'accorder pour dire que l'utilisation de Web Storage
est la voie à suivre plutôt que de bons vieux cookies
. Nous voulons que le JWT soit persistant entre les redémarrages du navigateur, utilisons donc Local Storage
, ne pas Session Storage
...
Maintenant, l'utilisateur peut redémarrer son navigateur et il sera toujours authentifié sur example1.com , tant que le jeton JWT n'a pas expiré!
Aussi, si example1.com doit faire une requête Ajax à un autre de nos domaines, je comprends la configuration CORS le permettrait. Mais notre principal cas d'utilisation n'est pas les requêtes interdomaines, mais la solution = single sign-on!
Par conséquent, la question principale:
Maintenant, quel devrait être le flux, si l'utilisateur accède à example2.com et que nous souhaitons qu'il soit authentifié à l'aide du jeton JWT qu'il possède déjà? Local Storage
ne semble pas autoriser l'accès interdomaine. Le navigateur ne peut donc pas lire le jeton JWT pour envoyer des requêtes à example2.com !
Devrait :
Nous ne voulons pas de fantaisie, nous serions heureux avec la solution la plus utilisée!
L'utilisateur doit à nouveau être redirigé vers le serveur d'authentification et obtenir un nouveau jeton (JWT), spécifiquement conçu pour example2.com. C’est ainsi que fonctionne OpenID Connect et tout autre protocole SSO fédéré entre domaines.
Rediriger l'utilisateur vers le service d'authentification central lorsque l'utilisateur n'est pas connecté pour demander des informations d'identification et émettre un nouveau jeton d'authentification est le scénario courant dans les systèmes à authentification unique utilisant des protocoles connus, tels que oauth2 ou OpenIdConnect.
Cependant, lorsque ce schéma est utilisé entre domaines, l’inconvénient principal est que l’utilisateur sera authentifié chaque fois qu’il accédera à un autre domaine en raison de la règle de même origine : le jeton de session ne peut pas être partagé entre les domaines. Par conséquent, le SSO traitera l'utilisateur comme non authentifié.
example2.com
ne peut pas accéder aux données de example1.com
mais il existe une technique permettant de partager des données entre domaines à l’aide du navigateur localStorage/cookies et d’un iframe pointant vers un domaine intermédiaire sso.example.com
Pour authentifier l'utilisateur dans example1.com
, redirigez-le vers le serveur d'authentification dans sso.example.com
, émettez un JWT après l’authentification et stockez-le dans le stockage local de ce domaine. Après cela, redirigez l'utilisateur vers le domaine d'origine example1.com
Créer un iframe dans example2.com
pointant vers sso.example.com
. L'iframe dans sso.example.com lit le jeton JWT et envoie un message à la page parent
La page parent reçoit le message et le jeton attaché continue avec le flux SSO.
Il n'y a pas de problème avec la politique de même origine car sso.example.com
a accès à son stockage local et la communication entre iframe et la page parente est autorisée si Origine et destination se reconnaissent (voir http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage )
Pour simplifier le développement, nous avons récemment publié une authentification unique de domaine avec JWT à l’adresse https://github.com/Aralink/ssojwt
Cette méthode est parfaitement compatible avec les flux SSO. Il s'agit simplement d'un moyen de partager le jeton d'authentification sans redirections et d'éviter les connexions inutiles lorsque les domaines sont fédérés.
Je ne sais pas si cela répond à votre question, mais si votre objectif principal est l’authentification unique, je pense qu’un simple proxy inverse résoudrait votre problème (du moins le stockage interdomaine).
Donc example1.com example2.com
deviendrait quelque chose comme
exemple.com/exemple1
exemple.com/exemple2
(Et du côté de l'utilisateur, c'est généralement plus propre)
Si ce n'est pas une option, vous devrez peut-être configurer votre ordinateur de manière à ce que lorsqu'un utilisateur s'authentifie dans un domaine, il utilise AJAX/hidden iframes pour créer une authentification avec les autres domaines (envoi d'un jeton 1 fois via url si vous devez ).
si ce n’est pas une option envisageable, vous devrez peut-être utiliser un nom d’utilisateur + un code PIN, car les navigateurs sont de plus en plus stricts en ce qui concerne l’interaction entre domaines.