web-dev-qa-db-fra.com

Facebook OAuth 2.0 "code" et "token"

Pourquoi avez-vous besoin à la fois d'un "code" et d'un "jeton" dans le flux d'authentification Facebook OAuth2 comme décrit ici: https://developers.facebook.com/docs/authentication/ ?

Si vous regardez la OAuth ( https://developers.facebook.com/docs/reference/dialogs/oauth/ ), il semble que vous ne jamais utiliser le jeton pour récupérer des informations sur l'utilisateur, et si vous spécifiez le response_type paramètre comme token ou code,token, vous obtenez le jeton la première fois.

Pourquoi avez-vous besoin d'obtenir un "code", puis d'utiliser le code pour obtenir un "jeton" plutôt que d'obtenir le jeton directement?

Je suppose que je ne comprends pas quelque chose de fondamental sur la façon dont OAuth fonctionne, mais il semble que vous évitiez la demande de https://graph.facebook.com/oauth/access_token entièrement si vous obtenez le jeton la première fois avec la boîte de dialogue.

60
jkeesh

Prenons un exemple simple pour différencier le code d'authentification par rapport au jeton d'accès.

En tant qu'utilisateur, vous voulez essayer une nouvelle application Facebook appelée Highjack. Vous cliquez donc sur l'application et l'application Highjack. vous demande de vous connecter à votre compte Facebook. Lorsque vous avez terminé, Facebook génère un code d'authentification pour vous.

Ce code est ensuite transmis au serveur Highjack qui utilise son propre identifiant client FB, son secret FB et votre code d'authentification pour obtenir un jeton d'accès.

Dans l'exemple ci-dessus, le code d'authentification confirme que vous êtes un utilisateur FB valide. Mais la deuxième étape dit "en tant qu'utilisateur FB, vous donnez accès à l'application Highjack pour certaines ressources".

Si l'application Highjack voulait une autorisation implicite (c'est-à-dire un jeton d'accès direct), le jeton d'accès serait également visible pour vous depuis son échange avec le navigateur. Cela signifie que vous pouvez désormais appeler toutes les API Facebook au nom de Highjack à l'aide du jeton d'accès. (Vous ne pouvez utiliser le jeton d'accès que pour obtenir vos informations personnelles, mais Facebook n'a aucun moyen de savoir qui appelle leurs API.)

Puisque nous avons 2 parties (You et Highjack) s'authentifiant avec Facebook, nous avons ce mécanisme à 2 volets.

41
Kris Subramanian

Emprunté sans vergogne à Documentation Salesforce :

Code d'autorisation

Un code d'autorisation est un jeton de courte durée représentant l'autorisation d'accès de l'utilisateur, créé par le serveur d'autorisation et transmis à l'application client via le navigateur. L'application cliente envoie le code d'autorisation au serveur d'autorisation pour obtenir un jeton d'accès et, éventuellement, un jeton d'actualisation.

Jeton d'accès Le jeton d'accès est utilisé par le client pour effectuer des demandes authentifiées au nom de l'utilisateur final. Il a une durée de vie plus longue que le code d'autorisation, généralement de l'ordre des minutes ou des heures. Lorsque le jeton d'accès expire, les tentatives d'utilisation échouent et un nouveau jeton d'accès doit être obtenu via un jeton d'actualisation.

27
Drew

De la spécification OAuth 2. :

Le code d'autorisation offre quelques avantages de sécurité importants tels que la possibilité d'authentifier le client et la transmission du jeton d'accès directement au client sans le passer par l'agent utilisateur du propriétaire de la ressource, l'exposant potentiellement à d'autres, y compris le propriétaire de la ressource .

Donc, fondamentalement - la principale raison est de limiter le nombre d'acteurs obtenant le jeton d'accès.

La réponse "token" est principalement destinée aux clients qui vivent dans le navigateur (par exemple: client JavaScript).

21
Scott T.

Si vous regardez le flux de code d'autorisation OAuth type , oui, il y a deux étapes pour l'actuaire:

1. <user_session_id, client_id> => authorization_code
2. <client_id, redirect_uri, authorization_code, client_secret> => access_token, refresh_token

À l'étape 1: l'utilisateur indique au serveur OAuth que "je veux autoriser ce client (client_id) à accéder à ma ressource. Voici mon authentification (user_session_id ou quoi d'autre)"

À l'étape 2: le client (client_id) indique au serveur OAuth) que "J'ai l'autorisation de l'utilisateur (code_autorisation), donnez-moi un jeton d'accès pour un accès ultérieur. Et ceci est mon authentification (client_id & client_secret) "

Vous voyez, si nous omettons l'étape 2, alors il n'y a aucune garantie pour l'authentification du client. Tout client peut appeler l'étape 1 avec un autre client_id et obtenir un jeton d'accès pour ce client_id au lieu du sien. C'est pourquoi nous avons besoin de l'étape 2.

Si vous voulez vraiment combiner les étapes 1 et 2, vous pouvez faire quelque chose comme ceci:

<client_id, redirect_uri, client_secret> => access_token, refresh_token

Nous utilisons cette approche dans notre plate-forme Open Api, et nous n'avons pas encore trouvé de problème de sécurité.

BTW, il existe réellement un type de subvention implicite , c'est-à-dire:

<client_id, redirect_uri> => access_token, refresh_token

Il est généralement applicable aux applications clientes uniquement sans serveur. Dans ce cas, le serveur OAuth doit s'assurer que l'URI de redirection appartient à ce client (idem pour le registre redirect_uri, par exemple)

7
arganzheng

La confusion est venue parce que l'utilisateur en son nom et non l'application cliente s'authentifie auprès du serveur d'autorisation (c'est-à-dire facebook). Il est très simple de sécuriser l'application client (avec https) puis l'agent utilisateur (navigateur).

Voici la formulation originale de IETF-oauth ( http://tools.ietf.org/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4 ):

3.4. Code d'autorisation

Un code d'autorisation représente le résultat intermédiaire d'un processus d'autorisation d'utilisateur final réussi et est utilisé par le client pour obtenir un jeton d'accès et d'actualisation. Les codes d'autorisation sont envoyés à l'URI de redirection du client au lieu de jetons à deux fins.

  1. Les flux basés sur le navigateur exposent les paramètres du protocole aux attaquants potentiels via les paramètres de requête URI (référent HTTP), le cache du navigateur ou les entrées du fichier journal et peuvent être relus. Afin de réduire cette menace, des codes d'autorisation de courte durée sont passés à la place des jetons et échangés contre des jetons via une connexion directe plus sécurisée entre le client et le serveur d'autorisation.

  2. Il est beaucoup plus simple d'authentifier des clients lors de la demande directe entre le client et le serveur d'autorisation que dans le contexte de la demande d'autorisation indirecte. Ce dernier nécessiterait des signatures numériques.

5
Eitan Rimon

Réponse) Vous avez besoin/voulez le code et le jeton pour plus de sécurité.

Selon Nate Barbettini, nous voulons l'étape supplémentaire consistant à échanger le code d'authentification pour le jeton d'accès, car le code d'authentification peut être utilisé dans le canal avant (moins sécurisé), et le jeton d'accès peut être utilisé dans le canal arrière (plus sécurisé) .

Ainsi, l'avantage de sécurité est que le jeton d'accès n'est pas exposé au navigateur et ne peut donc pas être intercepté/récupéré à partir d'un navigateur. Nous faisons davantage confiance au serveur Web, qui communique via des canaux de retour. Le jeton d'accès, qui est secret, peut alors rester sur le serveur Web et ne pas être exposé au navigateur (c'est-à-dire les canaux avant).

Pour plus d'informations, regardez cette fantastique vidéo:

OAuth 2.0 et OpenID Connect (en anglais simple) https://youtu.be/996OiexHze0?t=26m30s (Démarrer 26 min)

4
Michael R

Théoriquement,

  • Les jetons d'accès ne peuvent pas nous dire si l'utilisateur s'est authentifié, mais le code d'authentification le fait.
  • Le code d'authentification ne doit pas être utilisé pour accéder à une API, mais le jeton d'accès doit l'être.

Si vous avez une application d'une seule page ou une application mobile sans backend ou minimum, votre application peut vouloir accéder aux données FB de l'utilisateur directement au frontend. Par conséquent, le jeton d'accès est fourni.

Dans un autre cas, vous voudrez peut-être qu'un utilisateur s'inscrive/se connecte à votre application en utilisant un fournisseur de services d'authentification externe comme Facebook, Google etc. Dans ce cas, votre frontend enverra le code d'authentification au backend qui peut être utilisé pour obtenir un jeton d'accès de Facebook sur le serveur. Maintenant, votre serveur est activé pour accéder aux données FB de l'utilisateur à partir du serveur.

enter image description here

3
Amit Kumar Gupta

Fondamentalement, en tant qu'extension de réponse de Lix , la route du code d'accès permet à un propriétaire de ressource (c'est-à-dire l'utilisateur Facebook) de révoquer l'autorisation pour son agent utilisateur (c'est-à-dire son navigateur), par ex. en vous déconnectant, sans révoquer l'autorisation pour un client hors ligne (c'est-à-dire votre application). Si cela n'est pas important, il n'est pas nécessaire d'utiliser l'itinéraire du code d'accès.

En outre, le code d'accès est fourni pour garantir que le jeton fourni à un serveur est effectivement enregistré auprès du propriétaire de la ressource (c'est-à-dire l'utilisateur Facebook), et non pas de l'agent utilisateur (ou d'un homme du milieu).

Cela semble similaire à la question de choisir le flux d'octroi de code implicite ou d'autorisation. En fait, voici à quoi ressemble un point de vue opposé?! .

Aussi, comme Drew a mentionné ,

Lorsque le jeton d'accès expire, les tentatives d'utilisation échouent et un nouveau jeton d'accès doit être obtenu via un jeton d'actualisation.

un autre élément est le jeton d'actualisation, mais je ne vois pas que cela soit trop bien expliqué dans les documents FB. Si je ne me trompe pas, la subvention implicite (le jeton direct) devrait être de très courte durée, mais cela doit être appliqué et FB.js semble en cacher beaucoup (celui-ci, je ne l'ai pas examiné aussi profondément) .

Si j'ai raison, le code%20token est une optimisation permettant à la fois à l'agent utilisateur d'avoir un jeton et au serveur d'initier le processus d'échange de jetons en une seule demande (car tout ce qui se fait sur le réseau IO est considéré comme coûteux, en particulier pour un agent utilisateur).

3
dchoi-vindicogroup

C'est parce que le jeton d'accès est donné à un client AUTHENTIFIÉ (application tierce) en utilisant un secret partagé que seuls FB et le client connaissent. La seule façon pour l'utilisateur de demander directement le jeton d'accès est de connaître le secret partagé, ce qui rendrait le secret public et pourrait conduire à une attaque de l'homme du milieu. En outre, alors que FB peut garantir une connexion sécurisée à l'utilisateur, FB ne peut pas garantir que le transfert du jeton au client est sécurisé. Cependant, FB (et OAuth2) nécessite une connexion sécurisée entre le client et FB. Le jeton d'accès est lié à l'ID public du client (généralement haché), ce qui signifie que seule l'application cliente d'origine peut l'utiliser pour demander le jeton car le secret est envoyé avec le code d'autorisation pour obtenir le jeton d'accès.

1
Justin Ehrlich