web-dev-qa-db-fra.com

Comment implémenter l'authentification unique entre domaines et connexion automatique sans redirection de navigateur pour les utilisateurs non connectés?

J'ai besoin de mettre en œuvre une solution SSO avec les exigences suivantes:

  1. Cross-domain: Supposons que j'ai a.com, b.com et sso.com. Si je me connecte via a.com, Je ne devrais pas avoir besoin de me connecter lorsque je visite b.com.
  2. Centralisé: Utilisateur non connecté en cliquant sur "Connexion" sur a.com s'affiche un écran de connexion hébergé sur sso.com. Les informations d'identification sont vérifiées par sso.com dans la source de données qui ne lui est accessible.
  3. Connexion automatique: Si l'utilisateur s'est connecté à a.com, puis visite b.com, ils seront immédiatement connectés. C'est-à-dire le b.com, au lieu d'un lien "Login", nous voulons afficher tout de suite leur nom d'utilisateur, etc - sans avoir besoin de cliquer sur quoi que ce soit.
  4. Pas de redirection pour les utilisateurs anonymes: La grande majorité de mes utilisateurs utiliseront les sites sans avoir de compte. Par conséquent, lorsqu'ils arrivent pour la première fois à a.com, ou b.com, il ne doit pas y avoir de redirection rapide de la page entière vers sso.com et retour pour vérifier s'ils sont connectés. Une telle redirection serait mauvaise pour le référencement et la latence.

Pour les quelques utilisateurs qui se sont connectés à a.com puis allez à b.com (ou vice-versa), une redirection est acceptable.

Il existe de nombreux exemples sur le Web pour l'authentification unique, en particulier avec OAuth2, OpenID Connect et CAS, mais je n'ai pas pu trouver de recette pour ces exigences spécifiques. Le plus proche est le guide Stackoverflow SSO ( ici ), mais ils ont des exigences supplémentaires que je n'ai pas (par exemple, la connexion devrait toujours fonctionner si le serveur SSO est en panne).

10
Jan Żankowski

Il me semble que ce schéma OpenID Connect devrait le faire. Notez cependant que je ne suis pas un expert en sécurité, alors ne l'utilisez pas sans confirmation supplémentaire.

  1. L'utilisateur n'est pas connecté à a.com, b.com, sso.com.
  2. L'utilisateur accède à a.com, clique sur "Connexion".
  3. Rediriger vers sso.com, avec URL de retour sur a.com comme param.
  4. L'utilisateur fournit des informations d'identification valides. sso.com les accepte, redirige vers a.com avec le code d'autorisation comme paramètre. Il existe également un cookie de session SSO pour sso.com sur la réponse de redirection.
  5. Le navigateur suit la redirection, interroge a.com. a.com le serveur envoie le code d'autorisation à sso.com en backend, reçoit le jeton d'accès et le jeton d'identification, définit le cookie de session sur a.com. L'utilisateur est maintenant connecté sur a.com.
  6. L'utilisateur accède à b.com.
  7. Javascript sur b.com effectue un CORS silencieux AJAX appel à sso.com, vers un point de terminaison personnalisé (par exemple sso.com/has-sso-session). Le point de terminaison répond essentiellement par true/false en fonction de la présence d'un cookie SSO sur la demande.
  8. Si la réponse est:
    • true, Javascript redirige le navigateur vers sso.com, avec URL de retour sur b.comas param. Cela déclenche une authentification OpenID Connect régulière, qui sera automatique car l'utilisateur dispose d'un cookie SSO. À la fin de celui-ci, b.com le serveur envoie le code d'autorisation à sso.com en backend, reçoit le jeton d'accès et le jeton d'identification, définit le cookie de session sur b.com. L'utilisateur est maintenant connecté sur b.com.
    • false, Javascript définit un SSO check failed cookie de session sur b.com. Cela empêche d'autres vérifications lors de la navigation b.com, sauf si l'utilisateur clique sur "Connexion".
5
Jan Żankowski

La façon la plus simple et la plus simple de vous connecter sans aucune redirection consiste à exécuter toutes vos applications sur des sous-domaines (a.site.com, b.site.com). Les sous-domaines peuvent partager des cookies au niveau du domaine, afin que votre application reçoive le cookie de connexion dès la première demande.

Si vous souhaitez que vos applications se trouvent sur plusieurs domaines principaux non liés (a.com, b.com), le mieux que vous puissiez faire est d'avoir un JavaScript qui fait une demande interdomaine au service SSO au chargement de la page pour décider s'il doit procéder à la capture d'un jeton d'accès. Cela n'affectera pas le référencement, car les araignées n'exécutent pas JavaScript et n'ajouteront pas de latence pour l'utilisateur anonyme, car le chargement initial de la page par un utilisateur non connecté rendra la version anon de la page.

2
Lie Ryan