Comment dois-je concevoir un service Web RESTful pour utiliser une tierce partie (c'est-à-dire Google, Facebook, Twitter) pour l'authentification?

25

Pour mon travail, nous avons un bon service Web RESTful que nous avons construit que nous utilisons pour piloter quelques sites Web que nous avons. Fondamentalement, le webservice vous permet de créer et de travailler avec des tickets de support, et le site Web est responsable de l'interface. Toute demande de service Web utilise un en-tête d'authentification que nous utilisons pour valider l'utilisateur et son mot de passe pour chaque appel.

Cette année, nous cherchons à élargir nos options de connexion afin que les utilisateurs du site Web puissent se connecter via Google, Twitter et Facebook (éventuellement d'autres). Cependant, j'ai beaucoup de mal à comprendre comment procéder pour que le service Web puisse utiliser les fournisseurs d'authentification tiers pour garantir que les utilisateurs sont bien ceux qu'ils disent être. Existe-t-il des meilleures pratiques pour savoir comment procéder?

Actuellement, nous pensons que le site Web gère l'authentification des utilisateurs eux-mêmes, puis utilise un nouvel appel setSessionId qui enregistre leur session en cours avec le serveur Web principal. Chaque demande supplémentaire adressée au webservice transmettra cet identifiant de session et le validera. Cela semble correct, mais j'ai le sentiment que je n'y pense pas et que toute ma navigation sur le forum et la lecture des spécifications oauth et openid me déroutent plus. Des conseils pour résoudre ce problème?

Ralph Callaway
la source
rien de mal à ce que vous proposez. je trouve plus facile de regarder le code d'exemple d'intégration openid que les spécifications oauth et openid réelles ...
spaceman
Quelle langue / plateforme utilisez-vous? Vous n'avez pas besoin de réinventer la roue, car il existe des cadres pour vous aider considérablement. :)
RobM
@Rob Le webservice est hébergé sur Salesforce.com, mais est accessible via un proxy qui à ce jour est Node.js. Cela dit, il semble que la question générale s'appliquerait à toutes les plateformes. Et oui, j'espère utiliser un cadre plutôt que de réinventer la roue, mais je ne sais pas quelle roue utiliser.
Ralph Callaway
@Ralph Yep, la question générale est indépendante de la plate-forme, mais elle a des implications pratiques, car la plate-forme réduira généralement un peu vos options de cadre. Vous avez donc une application frontale personnalisée utilisant node.js pour un service Web hébergé par Salesforce et un référentiel de données? Avez-vous besoin de stocker des informations sur l'utilisateur / l'identité dans le backend, ou simplement une authentification et une autorisation sur les actions dans le front-end?
RobM
@RobM oui, nous voulons stocker les informations utilisateur sur le backend, c'est-à-dire le courrier électronique, le prénom, le nom de famille, ainsi que tout ce qui est nécessaire pour valider les futurs appels des consommateurs du service Web une fois qu'ils ont été authentifiés.
Ralph Callaway

Réponses:

14

Il semble qu'il y ait deux objectifs:

  1. Authentification facile pour les utilisateurs finaux avec leurs comptes sociaux existants
  2. Facile pour les développeurs utilisant votre webservice

Autoriser des personnes à utiliser des ressources sur votre site fait d'OAuth2 un mécanisme préféré en raison de la popularité et de la disponibilité des bibliothèques clientes.

1. Facile pour les utilisateurs finaux à s'authentifier avec leurs comptes sociaux existants

L'utilisateur final visite un site qui utilise votre API et choisit de se connecter. Ils sont envoyés à votre page de connexion OAuth. Votre page de connexion affiche une invite de nom d'utilisateur et de mot de passe normale pour les comptes gérés sur votre site et un ensemble de boutons d'authentification sociale où ils peuvent cliquer pour se connecter via un site comme Facebook. Lorsque l'utilisateur choisit Facebook, vous le redirigez vers Facebook pour approuver le choix (démarrage du flux d'authentification Facebook). Lorsque l'utilisateur final termine la connexion sur Facebook, il est redirigé vers votre site.

Lorsque l'utilisateur est redirigé vers votre site à partir de Facebook, vous enregistrez les informations de cet utilisateur dans un enregistrement d'utilisateur dans votre base de données, puis générez une nouvelle session pour cet utilisateur. Vous redirigez immédiatement l'utilisateur final vers son site en aval d'origine avec le oauth access_token, complétant le flux oauth d'origine.

2. Facile pour les développeurs utilisant votre webservice

Si vous êtes le fournisseur d'autorisation, vous devez créer une interface simple pour que les développeurs dépendent de ce qui ne change pas chaque fois que vous ajoutez un nouveau fournisseur d'authentification en amont qui n'implémente pas parfaitement oauth. C'est pourquoi je crois que vous devriez implémenter un site fournisseur OAuth2 et que ce site devrait être un consommateur des sites d'authentification sociale.

Pour le développeur utilisant votre belle API de repos, il ne sera pas au courant de l'interaction Facebook, sauf si vous choisissez de lui donner un indice via le post de capture de session (par exemple).

TL; DR

Faites en sorte que les utilisateurs de vos API soient comme vous en implémentant OAuth2 et en masquant les complexités d'authentification sociale. Vous pouvez, pendant votre flux oauth pour vos sites en aval, déclencher un flux oauth supplémentaire avec facebook.

Image car image == mots * 1000:

entrez la description de l'image ici

Pouvons-nous appeler cela oauth2-piggy-back?

Flux pas à pas

  1. L'utilisateur final visite le site qui utilise votre API
  2. L'utilisateur final est envoyé sur votre site pour autoriser ou vous inscrire (oauth2)
  3. L'utilisateur final choisit l'authentification sociale, clique sur le bouton de connexion Facebook
  4. Votre site installe un cookie ou le place statedans le facebook oauth pour savoir d'où vient l'utilisateur
  5. L'utilisateur final est redirigé vers Facebook et accepte la connexion sur le site Facebook
  6. L'utilisateur final est redirigé vers votre site pour terminer le processus d'authentification facebook
  7. Vous recherchez ou créez l'utilisateur dans votre base de données
  8. Vous créez une nouvelle session sur votre serveur
  9. Vous redirigez l'utilisateur vers son site d'origine avec votre jeton de session
James Sullivan
la source
5

Comment le rendre extensible

Vous devez d'abord remarquer que toutes ces API utilisent le même mécanisme de connexion. Elles utilisent toutes OAuth pour leur authentification. Vous devez en tirer parti en commençant par une bibliothèque OAuth générale. N'utilisez pas leurs propres bibliothèques pour l'authentification, elles seront inutilisables pour d'autres fournisseurs. Si vous maîtrisez OAuth2, il est assez facile d'ajouter plus de fournisseurs.

Vous avez malheureusement besoin de deux d'entre eux, car Twitter n'a toujours pas sauté dans le train OAuth2.

OAuth a besoin de vous pour créer une interface pour la partie d'authentification. Les jetons seront échangés serveur à serveur. Créez un point d'entrée qui peut gérer toutes les communications.

Le jeton doit être stocké dans une table distincte de votre compte, car il peut s'agir de plusieurs jetons et de plusieurs profils liés. Certains services vous donnent deux jetons, l'un d'eux est un jeton d'actualisation.

Vous concevez maintenant une interface qui encapsule les autres fonctionnalités dont vous avez besoin. Je voudrais personnellement configurer un service REST distinct pour cela. De cette façon, vous pouvez facilement étendre l'authentification à d'autres endroits.
Certains services utilisent JSON pour communiquer, d'autres optent pour XML, etc. Pour l'utilisateur frontal, vous devez tous les unifier. C'est un processus assez douloureux, mais il est possible de dériver ici des bases communes.

Un autre problème ici est que tous les services n'offrent pas les mêmes fonctionnalités. Cela peut signifier que vos services ne peuvent pas fournir l'API complète comme vous l'avez spécifié. Vous devez avoir une stratégie ici, qui permet de rétrograder l'application avec élégance.

Tout cela vous permettra d'ajouter facilement de nouveaux fournisseurs tiers.

Problèmes de jeton

Les jetons sont limités dans le temps, vous avez donc besoin de quelques tâches cron, qui peuvent vérifier si le jeton est toujours utilisable, sinon vous devez le supprimer. Vous pouvez également actualiser un jeton par ce mécanisme.

Il arrive parfois qu'un utilisateur rétracte le jeton. Soyez prêt pour cela.

Stockage de données

Si vous avez cette conception, vous devez penser aux données dont vous avez besoin. Cela découle en partie de l'interface que vous venez de créer. Concevez quelques tableaux pour cela et regardez si les données sont réellement récupérables. Certains services ne vous permettent pas de récupérer beaucoup de données. Vous devez également tenir compte du fait que plus vous avez besoin de données, plus les messages de confidentialité deviennent lourds. Soyez donc modeste dans vos besoins, sinon les utilisateurs ne l'utiliseront pas.

Pour une vérification supplémentaire, vous pouvez stocker les profils dans une table distincte mais liée à vos utilisateurs. Cela vous fournira beaucoup plus d'informations sur quelqu'un.

Vérifiez également vos lois locales, pour certaines données, vous avez besoin de précautions supplémentaires.

Dernière chose Ne faites pas la faute si vous ne créez pas de compte sur vos propres services. Si l'utilisateur est banni de Facebook, il ne pourra effectivement pas se connecter à votre service. C'est une situation que vous ne voulez pas créer. C'est souvent négligé.

Edgar Klerks
la source
1

Je choisirais certainement la solution qui semble avoir déjà été trouvée: implémenter l'authentification tierce sur votre site Web client, puis associer ces jetons d'authentification tiers à vos comptes d'utilisateurs de site Web, puis déclencher enfin votre appel setSessionID s'identifier.

En fonction de l'architecture de votre site Web, l'utilisation d'une bibliothèque comme EveryAuth ou Passport peut vous être très utile.

Rex
la source
1

Mes deux cents: je n'ai jamais rien fait de tel auparavant et je ne sais pas comment fonctionnent les mécanismes de connexion FB, Twitter ou Google, mais quelques problèmes sont apparus dans ma tête dès que j'ai lu votre question:

  • Connexions multiples: que se passe-t-il si je me connecte avec mon compte Facebook un jour et mon compte Google le lendemain? Ou simultanément? Traitez-vous ces deux comptes comme des comptes uniques et distincts ou devriez-vous avoir une méthode pour associer les deux et me permettre d'accéder à mes billets dans les deux cas?
  • S'appuyer sur des identifiants externes: que se passe-t-il lorsque Facebook ou Twitter décident de changer l'apparence de leurs identifiants de compte? Pour illustrer cela, si BazLogin représente un compte unique en utilisant le code {4382-af56} mais décide qu'à partir de maintenant les comptes auront 12 chiffres parce que 8 ne suffisent pas, comment dire {1234-4382-af56} de {0000-4382 -af56}?

Nous pouvons résoudre ces deux problèmes en choisissant d'associer les comptes externes à un compte interne, et pas seulement un ID de session. Ensuite, une connexion externe pourrait être juste une passerelle vers la création d'un compte interne. Si je m'authentifie avec plusieurs méthodes de connexion, vous pouvez me dire que je suis déjà connecté. Si un fournisseur d'authentification externe change quelque chose sur lequel nous comptons, nous pourrions demander à l'utilisateur de fournir le nom et le mot de passe de son compte interne et de créer un nouvelle association pour les futures connexions.

Je ne suis pas sûr d'avoir abordé les questions que vous aviez en tête, mais vous n'avez pas vraiment mentionné de préoccupations concrètes. J'espère que ma réponse a été utile, de toute façon.

idobie
la source