35 votes

Session utilisateur transparente sur plusieurs sites (single sign-on + single sign-off)

J'ai plusieurs sites dans différents domaines : example.com , example.org , mail.example.com y passport.example.org . Tous les sites ont une apparence et une convivialité communes et devraient partager la même base d'utilisateurs.

Et dans ce cas extrême, je veux quand même que tous les sites de manière transparente (autant que possible) partager des sessions d'utilisateurs avec les propriétés clés suivantes :

  1. Authentification unique . Lorsque l'utilisateur se connecte à passport.example.org et visite tout autre site - il doit être considéré comme connecté.

    Les utilisateurs connectés obtiennent "Bonjour, $username " dans l'en-tête du site et différents menu de navigation, énumérant les services auxquels ils ont accès. S'il n'est pas connecté, au lieu de de l'accueil, il y a un lien "Sign on", qui pointe sur passport.example.org/signon .

    La liste des domaines de confiance est connue, ce qui rend la mise en œuvre assez simple. avec OpenID ou avec un protocole léger maison. Lorsque l'utilisateur visite le site pour la première fois je le redirige vers un endpoint d'authentification spécial à l'adresse suivante passport.example.org , qui le redirige ensuite silencieusement, avec les informations d'identité (ou l'identité anonyme "non signée"). identité anonyme). Pour la plupart des navigateurs, c'est complètement transparent. Évidemment, j'utilise des valeurs nonce pour lutter contre les boucles de redirection.

  2. Signature unique . Lorsque l'utilisateur clique sur "se déconnecter" dans l'en-tête de n'importe quel site la prochaine fois qu'il visite un site, il doit être considéré comme "non connecté".

    OpenID n'a pas été conçu pour cela. Mon idée actuelle (j'ai déjà une implémentation qui fonctionne partiellement) est la suivante partiellement fonctionnelle) est d'envoyer non pas l'identité de l'utilisateur, mais un jeton de session "global" et de partager la table des sessions globales (relation utilisateur global_session_token) dans la BD.

  3. Soutien aux robots et aux utilisateurs sans cuisson . Les sites ont des zones publiques, qui doivent être accessibles par les agents utilisateurs sans l'aide de cookies.

    Pour cette raison, la redirection que j'ai mentionnée dans (1) devient un problème, car pour chaque demande de page, je finirai par envoyer l'agent utilisateur vers le point de terminaison d'authentification et vice-versa. Non seulement cela perturbera les robots, mais cela polluera ma base de données de sessions avec des données sessions mortes à la naissance très rapidement. Et je n'ai absolument pas envie d'afficher "hey, vous n'avez pas activé les cookies, partez !", ce serait extrêmement impoli et décevant. décevant. Bien que j'aie besoin du support des cookies pour me connecter, je veux que les utilisateurs puissent lire librement ce à quoi servent les sites et ainsi de suite - sans aucune restriction.

    Et j'ai explicitement Ne le fais pas. ne veulent pas mettre les ID de session dans les URLs, sauf pour quelques transparentes transparentes entre domaines que j'ai mentionnées. Je pense que faire cela est un problème de sécurité et généralement une mauvaise chose.

    Et là, je suis presque à court d'idées.

Bon, je sais que c'est difficile, mais Google le fait en quelque sorte avec ( google.com , google. lotofgTLDs , gmail.com et ainsi de suite), n'est-ce pas ? Donc cela devrait être possible.

Je serais reconnaissant pour des idées de description de protocole (ce serait le mieux) ou des liens. vers des systèmes (soit du code à lire, soit des sites en direct à observer et à apprendre) qui ont déjà mis en œuvre avec succès quelque chose comme ça. déjà mis en œuvre avec succès quelque chose comme ça.

Pour résumer : Plusieurs domaines sans racine commune, base d'utilisateurs partagée, signature unique, signature unique, pas de cookies nécessaires pour naviguer anonymement.

Tous les sites sont sur le même réseau (mais reposent sur des serveurs différents) et partagent en partie la même base de données PostgreSQL (qui repose sur différents schémas de la même base de données). partagent la même base de données PostgreSQL (reposant dans les différents schémas de la même base de données). La plupart des sites sont écrits avec Python/Django, mais certains d'entre eux utilisent PHP et Ruby on Rails. Bien que je pense à quelque chose d'agnostique du point de vue du cadre et du langage, je serais reconnaissant de m'indiquer toute implémentation. Même si je ne suis pas en mesure de les utiliser, si je saisis l'idée de comment c'est fait, je serai peut-être en mesure de mettre en œuvre quelque chose de similaire.

31voto

Wim ten Brink Points 12422

Alors, laissez-moi vous expliquer un peu plus. (Toutes les URL sont fictives !) Comme je l'ai dit, le visiteur se rend à http://www.yourwebpage.com et indique qu'il veut se connecter. Il est redirigé vers http://your.loginpage.org?return=http://www.yourwebpage.com/Authenticated où il devra fournir son nom d'utilisateur et son mot de passe.
Lorsque les informations de son compte sont valides, il retourne à la page qui était fournie dans l'URL de connexion, mais avec un paramètre supplémentaire qui sera utilisé comme ID. Ainsi, il se rend à http://www.yourwebpage.com/Authenticated?ID=SharedSecret où SharedSecret serait un identifiant temporaire, valable pendant 30 secondes ou moins.
Lorsque votre page d'authentification est appelée, elle fait alors appel à une méthode partagée entre yourwebpage.com et loginpage.org pour rechercher les informations de compte de SharedSecret afin de récupérer un identifiant plus permanent. Cet identifiant permanent est stocké dans la session web de yourwebpage.com et ne doit JAMAIS être montré à l'utilisateur.
La méthode partagée peut être n'importe quoi. Si les deux serveurs se trouvent sur la même machine, ils peuvent simplement accéder à la même base de données. Sinon, ils pourraient communiquer avec un autre serveur par le biais de services Web. Il s'agirait d'une communication de serveur à serveur, donc peu importe que l'utilisateur soit un robot ou qu'il ne supporte pas les cookies. Cette partie ne sera pas remarquée par l'utilisateur.
La seule chose dont vous aurez à vous occuper est la session de l'utilisateur. Normalement, les utilisateurs reçoivent un ID de session stocké dans un cookie, mais il peut aussi faire partie de l'URL dans le cadre d'une requête GET. Il est cependant un peu plus sûr d'avoir l'ID de session dans une requête POST, en ajoutant un champ de saisie caché à votre formulaire.

Heureusement, plusieurs langages de développement Web prennent déjà en charge les sessions. Vous n'avez donc pas à vous soucier de la gestion des sessions et de l'envoi des identifiants de session. La technique est néanmoins intéressante. Et vous devez être conscient que les sessions doivent toujours être temporaires, car il existe un risque de détournement des identifiants de session.

Si vous devez gérer plusieurs sites sur différents domaines, vous devrez d'abord travailler sur la communication entre serveurs. Le plus simple serait de les laisser partager la même base de données, mais il est préférable de construire un service web autour de cette base de données, pour une protection supplémentaire. Assurez-vous que ce service web n'accepte que les requêtes provenant de vos propres domaines, afin d'ajouter encore un peu plus de protection.
Lorsque vous avez des connexions de serveur à serveur, l'utilisateur peut passer d'un domaine à l'autre et tant que vous transmettez un ID de session au nouveau domaine, l'utilisateur est connecté. Si l'utilisateur utilise des cookies, il est peu probable que la session se perde et qu'il doive se reconnecter. Sans cookies, il est possible que l'utilisateur doive se reconnecter pour obtenir un nouveau cookie si l'ID de session se perd entre deux pages de navigation. (Par exemple, le visiteur va visiter Google et revient ensuite sur votre site. Avec un cookie, la session pourrait être lue à partir du cookie. Sans cookie, la session est perdue car Google ne transmet pas l'ID de session.

N'oubliez pas que la transmission des identifiants de session entre différents domaines constitue un risque pour la sécurité. L'ID de session peut être détourné, ce qui permet à quelqu'un d'autre de se faire passer pour votre visiteur. Par conséquent, les identifiants de session doivent avoir une durée de vie courte et être masqués. Mais même si un pirate a accès à un identifiant de session, il n'aura pas encore un accès complet au compte lui-même. Il ne pourra pas intercepter la communication entre serveurs et ne pourra donc pas accéder à la base de données contenant vos informations d'utilisateur, à moins d'accéder directement à la page de connexion.

5voto

Wim ten Brink Points 12422

À ma connaissance, Google utilise uniquement un cookie pour le domaine "Google.com". Mais Google utilise également OpenID qui permet un mécanisme de connexion générique. En gros, cela fonctionne en vous redirigeant vers une page de connexion spéciale. Cette page de connexion détectera si vous êtes connecté ou non et si vous n'êtes pas connecté, elle vous demandera de vous connecter. Sinon, elle vous redirige directement vers la page suivante.

Ainsi, dans votre cas, un utilisateur ouvre somepage.example.com et la session de cette application n'a pas d'identifiant de connexion. L'application redirigera donc l'utilisateur vers logon.example.biz où il se connectera. Derrière cette page se trouve également une session et cette session indique que l'utilisateur est déjà connecté. (Ou pas, auquel cas l'utilisateur doit d'abord se connecter.) Elle redirige ensuite l'utilisateur vers somepage.example.com?sessionid=something où cet identifiant de session est stocké dans la session de somepage.example.com. Cette session saura également que l'utilisateur s'est connecté et, pour l'utilisateur, cela semble presque transparent.

En réalité, l'utilisateur est redirigé deux fois.

1voto

Evan Points 9261

Si toutes vos applications sont sur le même domaine, ce n'est pas trop difficile car vous pouvez utiliser un cookie au niveau du domaine pour gérer le contrôle de la session. (La gestion des sessions sans cookie est difficile, mais peut être réalisée, mais est difficile).

Cependant, vous avez indiqué certains sites sur le domaine exemple.com, et d'autres sur le domaine exemple.org.

En jouant un peu avec mon identifiant google, et d'autres sites orkut.com, il semble que lorsque vous atteignez une page qui nécessite des informations d'identification, il vous redirige vers un site commun pour la connexion au compte, qui vous redirige ensuite vers le site d'origine, en passant probablement une sorte de jeton de session dans l'URL. À partir de là, les serveurs d'orkut.com communiquent directement avec les serveurs de google.com pour vérifier le jeton et obtenir toutes les autres informations nécessaires sur l'utilisateur.

Plus d'informations sur les cookies au niveau du domaine comme demandé

Si vous avez deux sites, disons foo.example.com y bar.example.com, vous pouvez définir un cookie spécifique à l'hôte, mais vous pouvez également définir un cookie pour le domaine qui sera vu par tous les hôtes du domaine.

Donc, foo.example.com peut créer un cookie pour foo.example.com spécifiquement, et il ne sera vu que par lui-même, mais il peut également définir un cookie pour le domaine example.com, et lorsque l'utilisateur va sur bar.example.com ils verront aussi ce deuxième cookie.

Cependant, si vous avez aussi un site, snafu.example.org, il ne peut pas voir ce cookie de niveau de domaine qui foo car example.org y example.com sont deux domaines complètement différents.

Vous pouvez utiliser le cookie de niveau domaine pour conserver les informations de session sur les sites du même domaine.

La façon dont vous définissez les cookies au niveau du domaine dépend

1voto

Adrian Grigore Points 15993

Utilisez-vous ASP.NET? Si tel est le cas, vous souhaiterez peut-être consulter la propriété enableCrossAppRedirects .

1voto

Pour cette solution, pas besoin de serveur de passeport.

Signin

  1. Connexion
  2. Créer un jeton avec un identifiant de session crypté et d'autres informations.
  3. Montrer l'image avec le jeton de tous vos domaines pour la mise en place des cookies sur son.

Autorisation par cookie

  1. Vous avez déjà des cookies sur tous les domaines.

Se déconnecter

  1. Effacer le cookie
  2. Détruire la session
  3. Effacer la relation entre l'identifiant de l'utilisateur et l'identifiant de la dernière session dans la base de données (je pense que vous enregistrez l'identifiant de la session dans la table des utilisateurs pour remonter la session par le cookie).

Je ne peux pas essayer cette solution. Mais maintenant j'ai le même problème que vous (SSO) et j'essaierai cette solution demain.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X