Flux d'authentification unique utilisant JWT pour l'authentification interdomaine

112

Il existe de nombreuses informations sur le Web sur 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 d'authentification unique dans un environnement à plusieurs domaines .

Je travaille pour une entreprise qui a beaucoup de sites sur différents hébergeurs. 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: "OpenId Provider"). L'utilisateur s'authentifie sur ce serveur qui le redirige ensuite vers le site example1.com d' origine 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 jeton JWT réel plus tard, 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 requêtes, en passant le jeton JWT dans un en- Authenticationtête et le serveur est capable de vérifier le JWT signé et est donc capable d'identifier l'utilisateur. Agréable!

Première question :

Comment le jeton JWT doit-il être stocké sur le client? Il y a, encore une fois, beaucoup d'informations à ce sujet, et les gens semblent convenir que l'utilisation Web Storageest la voie à suivre plutôt que le bon vieux temps cookies. Nous voulons que le JWT soit persistant entre les redémarrages du navigateur, alors utilisons Local Storage, non Session Storage...

Maintenant, l'utilisateur peut redémarrer son navigateur et il sera toujours authentifié sur example1.com , tant que le jeton JWT n'est pas expiré!

De plus, si example1.com a besoin de faire une demande Ajax à un autre de nos domaines, je comprends que la configuration de CORS le permettrait. Mais notre principal cas d'utilisation ne concerne pas les requêtes inter-domaines, c'est d'avoir une solution d'authentification unique !

Par conséquent, la question principale:

Maintenant, quel devrait être le flux, si l'utilisateur accède à example2.com et que nous voulons qu'il soit authentifié, en utilisant le jeton JWT qu'il possède déjà? Local Storagene semble pas autoriser l'accès inter-domaines, donc à ce stade, le navigateur ne peut pas lire le jeton JWT pour faire des requêtes à example2.com !

Devrait :

  • L'utilisateur est-il redirigé vers le serveur d'authentification ? Lorsque l'utilisateur s'est authentifié par exemple1.com , le serveur d'authentification peut avoir placé un cookie sur l'utilisateur afin que cette nouvelle demande d'authentification pour exemple2.com puisse utiliser ce cookie pour voir que l'utilisateur est déjà authentifié et le redirige immédiatement vers exemple2.com avec le même jeton JWT?
  • Ou le navigateur, sur example2.com , peut-il accéder au jeton JWT sans avoir à accéder à nouveau au serveur d'authentification ? Je vois qu'il existe des solutions de stockage croisé , mais sont-elles largement utilisées? Sont-ils la solution suggérée pour un environnement SSO interdomaine?

Nous ne voulons rien d'extraordinaire, nous serions satisfaits de la solution la plus utilisée!

galvanotype
la source

Réponses:

28

L'utilisateur doit à nouveau être redirigé vers le serveur d'authentification et obtenir un nouveau jeton (JWT), un jeton spécifiquement ciblé pour example2.com. C'est ainsi que fonctionnent OpenID Connect et tout autre protocole SSO fédéré interdomaine.

Hans Z.
la source
15
Mais sans que l'utilisateur ait à renvoyer les informations d'authentification (nom d'utilisateur / mot de passe par exemple) puisqu'il s'agit d'un SSO, non? Alors comment ça a été fait? Le serveur d'authentification doit-il définir un cookie standard sur l'utilisateur la première fois, afin de pouvoir l'authentifier automatiquement lorsque cet utilisateur revient d'un nouveau domaine?
electrotype
7
Mais que faire si l'utilisateur a configuré le navigateur pour bloquer tous les cookies?
Christiaan Westerbeek
1
Je suppose qu'un avertissement devrait être placé sur les cookies que "le site peut ne pas fonctionner correctement si votre navigateur bloque les cookies"
AnBisw
la connexion unique n'implique pas nécessairement que l'utilisateur a une session en cours suivie par un cookie: sa caractéristique déterminante est que l'on réutilise les mêmes informations d'identification contre le même fournisseur d'identité pour accéder à différentes applications tierces, c'est-à-dire qu'aucun cookie n'est requis, juste réutiliser les mêmes creds
Hans Z.
35

La redirection de 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 d'authentification unique utilisant des protocoles bien connus tels que oauth2 ou OpenId Connect

Cependant, lorsque ce schéma est utilisé dans plusieurs domaines, le principal inconvénient est que l'utilisateur va être redirigé et authentifié chaque fois qu'il navigue vers un autre domaine en raison de la politique de même origine : le jeton d'accès ne peut pas être partagé entre les domaines ( example2.comne peut pas accéder aux données of example1.com), de sorte que le domaine cible traitera l'utilisateur comme non authentifié, le redirigeant vers le service SSO central.

Pour empêcher le service d'authentification de redemander les informations d'identification, il est courant d'avoir un cookie de session (pas un jeton d'accès), mais il existe une technique pour partager des données entre les domaines à l'aide du navigateur localStorage / cookies et d'un iframe pointant vers un domaine intermédiaire sso.example.com

  1. Pour authentifier l'utilisateur dans example1.com, redirigez-le vers le serveur d'authentification dans sso.example.com, émettez un JWT après authentification et stockez-le dans le localStorage de ce domaine. Après cela, redirigez l'utilisateur vers le domaine d'origine example1.com

  2. Créez un iframe en example2.compointant vers sso.example.com. L'iframe dans sso.example.com lit le jeton JWT et envoie un message à la page parent

  3. La page parent reçoit le message et obtient le jeton attaché en poursuivant le flux SSO

Il n'y a aucun problème avec la politique de même origine car sso.example.coma accès à son localStorage et la communication entre iframe et la page parent est autorisée si les domaines d'origine et cible se reconnaissent (voir http://blog.teamtreehouse.com/cross-domain- messagerie avec message postal )

Pour simplifier le développement, nous avons récemment publié un SSO interdomaine avec JWT sur 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

pedrofb
la source
3
En dehors de cette solution qui n'adhère pas à une norme, généralement dans le SSO interdomaine, on dépasse les frontières administratives et dans ce cas, l'utilisation du même JWT pour les deux domaines ouvrirait la possibilité pour un propriétaire d'application dans un domaine d'usurper l'identité de l'utilisateur dans l'autre. domain
Hans Z.
6
Merci @HansZ. Nous avons effectivement implémenté cette solution afin d'avoir une administration unique de plusieurs domaines avec des dizaines d'applications et les mêmes utilisateurs. Le fonctionnement est similaire au système Google (relativement parlant)
pedrofb
2

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 (au moins celui du stockage inter-domaines).

Donc, example1.com example2.com

deviendrait quelque chose comme

example.com/example1

example.com/example2

(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 pour que lorsqu'un utilisateur s'authentifie dans 1 domaine, il utilise AJAX / iframes cachés pour créer également une authentification avec les autres domaines (envoi d'un jeton 1 fois via url si vous devez ).

et si CE N'EST pas une option, vous devrez peut-être recourir au nom d'utilisateur + code PIN, car les navigateurs sont de plus en plus stricts sur les interactions entre domaines.

Tezra
la source