Conception pour l'authentification Facebook dans une application iOS qui accède également à un service Web sécurisé

402

Objectif: Autoriser un utilisateur à s'authentifier avec Facebook dans une application iOS qui nécessite l'accès à un service Web protégé que j'exécute.

Hypothèses: Un système d'authentification (et d'enregistrement) natif est en place pour les utilisateurs qui choisissent de ne pas utiliser Facebook pour se connecter.

Détails:

  • Supposons que nous voulons offrir la possibilité à un utilisateur de se connecter avec Facebook sans créer de compte / informations d'identification distinctes pour notre système.
  • Parce que nous prenons en charge notre propre mécanisme d'authentification natif (nom d'utilisateur et mot de passe), nous avons nos propres ID utilisateur et émettons un jeton d'authentification qui est utilisé pour les interactions ultérieures après la validation initiale des informations d'identification.

Je suis surpris que Facebook n'ait pas de meilleures pratiques à ce sujet dans sa documentation pour les développeurs. Toute la documentation existante suppose que vous intégrez l'authentification FB dans un site Web ou une application mobile autonome sans service nécessitant une authentification.

Voici mes premières réflexions sur la façon dont cela serait conçu, mais je veux une validation pour savoir si c'est correct.

  1. Le client affiche la connexion Facebook iOS
  2. L'utilisateur de l'interface utilisateur se connecte avec les informations d'identification Facebook et obtient un jeton d'accès
  3. L'application iOS transmet le jeton d'accès à notre serveur
  4. Notre serveur parle à l'API graphique FB en utilisant un jeton d'accès pour (a) valider le jeton et (b) obtenir l'ID utilisateur FB pour ce jeton d'accès.

    Par exemple, notre serveur appellerait https://graph.facebook.com/me/?access_token=XYZ qui retournerait des informations de profil dans un objet JSON

  5. En supposant qu'il est valide, notre serveur extrait l'ID utilisateur de l'objet JSON et vérifie si l'utilisateur a déjà un compte. Si c'est le cas, nous émettons notre propre ticket d'authentification au client à utiliser pour cette session. Si l'utilisateur n'a pas de compte, nous en créons un nouveau avec l'ID utilisateur Facebook, attribuons notre propre ID utilisateur unique et émettons notre ticket d'authentification.

  6. Le client transmet ensuite le ticket d'authentification aux interactions suivantes qui nécessitent une authentification.

Cela semble être la bonne approche pour moi, mais je ne sais pas si je manque quelque chose de incroyablement basique et que j'emprunte le mauvais chemin (compliqué).

TMC
la source
1
Comment cela a-t-il été résolu? J'envisage également de passer le jeton d'accès et de faire tourner l'utilisateur sur le serveur. Semble académique, mais je demande.
Chris Van Buskirk
C'était ma mise en œuvre à l'aide de rails et de devise: stackoverflow.com/questions/7232490/…
Matt
Pourquoi ne pas passer tout l'auth_hash au lieu d'avoir à faire deux appels à l'API FB (un depuis l'appareil iOS et une fois depuis le serveur)?
bsiddiqui
1
Que faire si vous souhaitez vous connecter à partir d'un autre appareil (ce qui signifie que vous n'avez pas votre ticket d'authentification)? Et si vous venez de recevoir un nouveau ticket d'authentification, qu'est-ce qui empêche quelqu'un de détourner l'identifiant / jeton facebook en cours de route et de l'utiliser sur son propre appareil?
Amitloaf
Par curiosité, à l'étape 5, pourquoi émettre votre propre ticket d'authentification? Ne pourriez-vous pas utiliser le jeton d'accès Facebook pour chaque appel de serveur suivant? Je me rends compte que cela nécessiterait un appel du serveur vers l'API Facebook pour chaque application -> appel serveur plutôt que juste le premier.
Anders

Réponses:

80

Je viens de m'en occuper moi-même, et voici la partie qui m'a mordu:

Dans votre étape 5 ... Il est possible pour un utilisateur de créer un compte avec vous entièrement distinct de son identifiant Facebook, non? Puis une autre fois, ils se connectent avec Facebook .... Et vous venez de leur créer un deuxième compte et perdu leur premier.

Il doit y avoir un moyen de se connecter à votre service Web, puis de se connecter à Facebook et de capturer l'association entre l'ID Facebook et le compte local.

En dehors de cela, votre plan semble solide.

Mise à jour : Facebook a ajouté un document décrivant un tel scénario ICI

Dan Ray
la source
7
Oui, j'y ai réfléchi et vous êtes sur place. Nous prévoyons de fusionner les comptes s'il s'agit de la même adresse e-mail, et sinon, nous allons créer une autre façon de les fusionner.
TMC
Quelle bibliothèque de serveur utilisez-vous côté serveur pour effectuer la demande?
TimLeung
7
@TimLeung - Je crois comprendre qu'un jeton d'accès incorpore l'ID d'application et que vous ne pouvez pas avoir de jeton d'accès SANS ID d'application intégré.
Dan Ray
1
@TimLeunge: Nous utilisons l'API Graph pour les demandes avec le jeton d'accès de l'utilisateur.
TMC
29

Utilisez https pour transmettre le jeton d'authentification à votre serveur, comme indiqué par Facebook

Partage de jetons d'accès

Nos politiques de données interdisent explicitement tout partage d'un jeton d'accès pour votre application avec toute autre application. Cependant, nous permettons aux développeurs de partager des jetons entre une implémentation native et une implémentation de serveur de la même application (c'est-à-dire en utilisant le même ID d'application) tant que le transfert a lieu en utilisant HTTPS.

zoomcrypt
la source
16

Un problème que je peux voir avec cette stratégie, c'est que quelqu'un peut vous donner un jeton d'accès obtenu pour une autre application Facebook. Pour autant que je sache, il n'y a aucun moyen de vérifier que le jeton d'accès est pour votre application, vous allez donc continuer à l'utiliser.

Cela ne semble pas très dangereux, cependant. Généralement, les personnes / applications essaient de protéger les jetons d'accès, plutôt que de les partager.

Un exploit possible serait que quelqu'un crée son propre site ou application mobile, obtienne des jetons d'accès pour ses utilisateurs et essaie de les authentifier à l'aide de votre API. Si cela réussit (l'utilisateur dispose d'un compte Facebook sur votre site), le site malveillant pourra utiliser votre API pour usurper l'identité de l'utilisateur.

C'est un peu long, mais je pense que cela pourrait fonctionner.

Modifier: il semble qu'il existe un moyen de valider le jeton d'accès après tout. Voir la réponse de @Daaniel à la question Obtenir l'ID d'application du jeton d'accès utilisateur (ou vérifier l'application source pour un jeton) .

ivant
la source
L'envoi appsecret_proofdevrait empêcher cela (voir ici )
Tony
@Tony, pouvez-vous expliquer comment l' appsecret_proofaide ici? Pour autant que je sache, cela sert à prouver à Facebook que le serveur connaît la clé secrète. Cependant, ivant faisait référence à une application malveillante obtenant des jetons puis les envoyant à votre API. Le serveur peut vérifier l'ID d'application, mais l'ID d'application peut être facilement usurpé par une application malveillante. Alors ... comment pourrait-on atténuer cela?
YSK
3
Vous pouvez vérifier que le jeton a été généré pour votre application via https://graph.facebook.com/app/?access_token=[user_access_token]laquelle renvoie l'ID de l'application, puis comparer les ID de l'application
Nader Alexan
4

votre solution fonctionne totalement.

Peut-être une alternative: pourquoi ne pas simplement recevoir l'e-mail du client à partir de la demande initiale de service social et l'envoyer à votre service Web? Le service Web pourrait simplement stocker l'e-mail, et peut-être aussi un social_provider. Je comprends que votre service Web ne pourra pas valider la provenance de l'e-mail, mais n'y a-t-il pas une relation de confiance élevée entre votre service Web et votre client? Si tel est le cas, il semble que vous puissiez dépendre de l'e-mail provenant du bon endroit. Quelqu'un, s'il vous plaît, faites-moi savoir quelle chose évidente qui me manque rend l'approche basée sur le courrier électronique idiote ...

Amsterdam
la source
3
Je pourrais facilement découvrir comment le client parle au serveur. Ensuite, je pouvais simplement lui envoyer des e-mails jusqu'à ce que je reçoive un coup. Il doit toujours y avoir une forme de vérification
Chris
5
Haute confiance et client? Jamais dans la même phrase, s'il vous plaît. Sauf phrase précédente bien sûr.
EralpB