Quelle est la différence entre le code d'autorisation OAuth et les workflows implicites? Quand utiliser chacun d'eux?

165

OAuth 2.0 a plusieurs flux de travail. J'ai quelques questions concernant les deux.

  1. Flux de code d'autorisation - L'utilisateur se connecte à partir de l'application cliente, le serveur d'autorisation renvoie un code d'autorisation à l'application. L'application échange ensuite le code d'autorisation contre un jeton d'accès.
  2. Flux d'octroi implicite - L'utilisateur se connecte à partir de l'application cliente, le serveur d'autorisation émet un jeton d'accès directement à l'application cliente.

Quelle est la différence entre les deux approches en termes de sécurité? Lequel est le plus sûr et pourquoi?

Je ne vois pas de raison pour laquelle une étape supplémentaire (échange du code d'autorisation pour le jeton) est ajoutée dans un flux de travail lorsque le serveur peut émettre directement un jeton d'accès.

Différents sites Web indiquent que le flux de code d'autorisation est utilisé lorsque l'application cliente peut sécuriser les informations d'identification. Pourquoi?

divyanshm
la source
A Guide to OAuth 2.0 Grants
Alexandru Marculescu

Réponses:

204

C'est access_tokence dont vous avez besoin pour appeler une ressource protégée (une API). Dans le flux de code d'autorisation, il y a 2 étapes pour l'obtenir:

  1. L'utilisateur doit s'authentifier et renvoyer un codeau consommateur d'API (appelé le «client»).
  2. Le "client" de l'API (généralement votre serveur web) échange le codeobtenu en # 1 contre un access_token, s'authentifiant avec un client_idetclient_secret
  3. Il peut ensuite appeler l'API avec l'extension access_token.

Donc, il y a une double vérification: l'utilisateur qui possède les ressources apparues via une API et le client utilisant l'API (par exemple une application Web). Les deux sont validés pour que l'accès soit accordé. Remarquez la nature «d'autorisation» d'OAuth ici: l'utilisateur accorde l'accès à sa ressource (via le coderenvoi après authentification) à une application, l'application obtient un access_token, et appelle au nom de l'utilisateur.

Dans le flux implicite, l'étape 2 est omise. Ainsi, après l'authentification de l'utilisateur, un access_tokenest renvoyé directement, que vous pouvez utiliser pour accéder à la ressource. L'API ne sait pas qui appelle cette API. N'importe qui avec access_tokenpeut, alors que dans l'exemple précédent, seule l'application Web le ferait (ce sont les composants internes normalement accessibles à personne)

Le flux implicite est généralement utilisé dans des scénarios où le stockage client idet client secretne sont pas recommandés (un dispositif par exemple, bien que beaucoup le font de toute façon). C'est ce que signifie l'avertissement. Les gens ont accès au code client et peuvent donc obtenir les informations d'identification et prétendre devenir des clients ressources. Dans le flux implicite, toutes les données sont volatiles et il n'y a rien de stocké dans l'application.

Eugenio Pace
la source
Merci pour votre explication, mais je ne comprends pas pourquoi nous avons besoin d'un autre flux de code d'autorisation. Nous pouvons atteindre le même résultat sur le serveur par un flux implicite (access_token) et un jeton d'actualisation. Il semble que la seule considération de sécurité du flux implicite est que access_code devrait avoir une courte durée de vie afin qu'il ne puisse pas être utilisé de serveur à serveur. OK, mais le jeton d'actualisation résout ce problème. Pourquoi devrions-nous utiliser un flux auth_code et demander access_token par celui sur le serveur pour obtenir access_code?
Mohammad Nikravan
Eh bien ... c'est ainsi que fonctionne le protocole. Vous voudrez peut-être lire l'analyse des menaces de spécification pour une référence plus détaillée sur les mérites de sécurité de l'un et de l'autre.
Eugenio Pace
Je sais que la réponse originale date de plus de 5 ans, mais c'est l'explication la plus simple et la plus claire que j'aie jamais lue. Merci @EugenioPace
Taha Ahmad
1
@ Madnik7G La raison est orthogonale à ce que cette réponse explique (magnifiquement): il pourrait y avoir un tiers impliqué. L'ensemble du flux est orchestré par un agent utilisateur (par exemple: le navigateur), mais à la fin, le serveur d'autorisation (par exemple: "Connexion avec Facebook") parlera directement avec le client (par exemple, votre BFF côté serveur) qui va finalement accéder à la ressource, de sorte que l'agent utilisateur n'ait jamais d'accès direct.
Daniel Langdon
Merci! Oui, il y a 3 communications en cours: le navigateur et l'AS 9, par exemple. Facebook). Telle est la /authorizedemande. Le navigateur et le site Web essayant d'appeler l'API (alias le client). C'est le redirect_uri+ coderenvoyé par l'AS après une authentification réussie. Enfin, le client appelle l'AS dans les coulisses, échangeant le codepour un access_token. C'est le token endpointdans la littérature. En général, l'AS n'appelle jamais personne. Il répond toujours.
Eugenio Pace du
52

J'ajouterai ici quelque chose qui, à mon avis, n'est pas clair dans les réponses ci-dessus:

  • Le flux de code d'autorisation permet au jeton d' accès final de ne jamais atteindre et de ne jamais être stocké sur la machine avec le navigateur / l'application . Le code d'autorisation temporaire est donné à la machine avec le navigateur / l'application, qui est ensuite envoyé à un serveur. Le serveur peut alors l'échanger avec un jeton d'accès complet et avoir accès aux API, etc. L'utilisateur avec le navigateur n'a accès à l'API que via le serveur avec le jeton.
  • Le flux implicite ne peut impliquer que deux parties et le jeton d'accès final est stocké sur le client avec le navigateur / l'application. Si ce navigateur / application est compromis, il en va de même pour leur jeton d'authentification, qui pourrait être dangereux.

tl; dr n'utilisez pas de flux implicite si vous ne faites pas confiance à la machine des utilisateurs pour détenir des jetons mais que vous faites confiance à vos propres serveurs.

George Powell
la source
12
re: L'utilisateur avec le navigateur a accès à l'API uniquement via le serveur avec le jeton. Mais le serveur doit envoyer quelque chose au navigateur afin que les demandes entrantes puissent être associées au jeton qui est conservé côté serveur. Un cookie si vous aimez. Si le serveur ne transmet pas le jeton au JS fonctionnant dans le navigateur, il doit transmettre autre chose, que le client (navigateur) doit transmettre au serveur, afin de permettre au serveur d'agir au nom du client particulier.
Cheeso
Oui, un cookie. Ainsi, vous devez configurer votre serveur et votre navigateur client pour qu'ils soient protégés contre la falsification de requêtes intersites.
Marcel
@Marcel j'aimerais savoir qu'une fois que nous avons obtenu le code, comment et où l'échange se produit pour obtenir le réel access_tokenavec l'aide de authorization code.
chirag soni
14

La différence entre les deux est que:

  1. Dans un flux implicite, le jeton est retourné directement via l'URL de redirection avec le signe "#" et cela est principalement utilisé dans les clients javascript ou les applications mobiles qui n'ont pas de côté serveur à part entière, et le client n'a pas besoin de fournir son secret dans certaines implémentations .

  2. Dans le flux de code d'autorisation, le code est renvoyé avec "?" pour être lisible par le côté serveur, le côté serveur doit fournir cette fois le secret client au jeton url pour obtenir le jeton en tant qu'objet json du serveur d'autorisation. Il est utilisé dans le cas où vous avez un serveur d'applications capable de gérer cela et de stocker le jeton d'utilisateur avec son profil sur son propre système, et principalement utilisé pour les applications mobiles courantes.

Cela dépend donc de la nature de votre application client, quel "code d'autorisation" plus sécurisé, car il demande le secret sur le client et le jeton, peut être envoyé entre le serveur d'autorisation et l'application client sur une connexion très sécurisée, et le fournisseur d'autorisation peut restreindre certains clients à n'utiliser que le «code d'autorisation» et interdire implicite

Bassem Reda Zohdy
la source
Le code d'autorisation est stocké côté serveur pendant 10 minutes pour Facebook. Cela a été publié dans leur modification du 5 décembre 2012. Ma question est principalement de savoir quelle est la différence entre les 2 en termes de sécurité / performance. Je sais ce que font les deux flux - mais quel est l'avantage d'utiliser le code d'autorisation - en ajoutant une étape supplémentaire au flux de travail.
divyanshm
il n'envoie pas le jeton à l'application utilisateur, la connexion entre l'application cliente et le serveur d'autorisation est cachée à l'utilisateur, et comme je l'ai mentionné, il pourrait s'agir d'un canal très sécurisé différent de celui de l'application utilisateur à l'application cliente.
Bassem Reda Zohdy
performances dans le code d'autorisation vous frappez le serveur d'authentification deux fois, donc cela prend plus de temps, le serveur client va également stocker le jeton utilisateur et cela ajoutera également plus de temps.
Bassem Reda Zohdy
2
Oh d'accord! J'aurais peut-être oublié cela. Donc, fondamentalement, le flux de code d'autorisation doit être utilisé par des systèmes où un serveur entier est un client - le navigateur fait la demande et obtient le code. Le code est envoyé au serveur client qui se connecte au serveur de ressources en toute sécurité. Suis-je bien compris? Le jeton d'accès n'atteint jamais la machine de l'utilisateur final?
divyanshm
1
Le jeton d'accès n'atteint jamais la machine de l'utilisateur final? oui, il est lié à votre profil avec le serveur d'application client.
Bassem Reda Zohdy
4

L'octroi implicite est similaire à l'octroi de code d'autorisation avec deux différences distinctes.

Il est destiné à être utilisé pour les clients basés sur des agents utilisateurs (par exemple, des applications Web à page unique) qui ne peuvent pas garder un client secret car tout le code d'application et le stockage sont facilement accessibles.

Deuxièmement, au lieu que le serveur d'autorisation renvoie un code d'autorisation qui est échangé contre un jeton d'accès, le serveur d'autorisation renvoie un jeton d'accès.

Veuillez trouver les détails ici http://oauth2.thephpleague.com/authorization-server/which-grant/

Lutfor
la source
1
Merci pour ce lien, cela m'a aidé à comprendre la différence entre chaque type de subvention et le moment de choisir chacun d'entre eux.
François POYER
3

Flux implicite

Avantages

  • Le plus simple à mettre en œuvre

Désavantages

  • Jetons d'accès visibles par le navigateur
  • L'origine des jetons d'accès ne peut pas être déterminée
  • Les jetons d'accès ne peuvent pas expirer (conformément à la politique de Google)

Flux de code d'autorisation

Avantages

  • Le plus sécurisé
  • Les jetons d'accès et les jetons d'actualisation ne peuvent être créés que si un secret partagé est connu
  • Peut être amélioré avec de nouvelles fonctionnalités de sécurité et UX lorsqu'elles sont disponibles

Désavantages

  • Doit implémenter plusieurs points de terminaison d'authentification

Citation: https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows

vlazzle
la source
2

Permettez-moi de résumer les points que j'ai appris des réponses ci-dessus et d'ajouter certaines de mes propres compréhensions.

Flux de code d'autorisation !!!

  • Si vous disposez d'un serveur d'applications Web qui agit en tant que client OAuth
  • Si vous voulez avoir un accès de longue durée
  • Si vous souhaitez avoir un accès hors ligne aux données
  • lorsque vous êtes responsable des appels API effectués par votre application
  • Si vous ne souhaitez pas divulguer votre jeton OAuth
  • Si vous ne souhaitez pas que votre application s'exécute via le flux d'autorisation chaque fois qu'elle a besoin d'accéder aux données. REMARQUE: le flux d'octroi implicite ne reçoit pas de jeton d'actualisation. Par conséquent, si le serveur d'autorisation expire régulièrement les jetons d'accès, votre application devra exécuter le flux d'autorisation chaque fois qu'elle en aura besoin.

Flux de subvention implicite !!!

  • Lorsque vous n'avez pas de serveur d'applications Web pour agir en tant que client OAuth
  • Si vous n'avez pas besoin d'un accès de longue durée, c'est-à-dire qu'un accès temporaire aux données est requis.
  • Si vous faites confiance au navigateur sur lequel votre application s'exécute et que vous craignez peu que le jeton d'accès soit divulgué aux utilisateurs non approuvés.
Aman Tuladhar
la source
2

Lequel est le plus sûr et pourquoi?

Les deux sont sécurisés, cela dépend de l'environnement dans lequel vous l'utilisez.

Je ne vois pas de raison pour laquelle une étape supplémentaire (échange du code d'autorisation pour le jeton) est ajoutée dans un flux de travail lorsque le serveur peut émettre directement un jeton d'accès.

C'est simple. Votre client n'est pas sécurisé. Voyons cela en détails.

Considérez que vous développez une application contre Instagram API, donc vous enregistrez votre APP avec Instagramet définissez ce dont API'svous avez besoin. Instagramvous fournira client_idetclient_secrect

Sur votre site Web, vous créez un lien qui dit. "Venez utiliser mon application". En cliquant dessus, votre application Web doit effectuer deux appels Instagram API.

Firstenvoyer une demande à Instagram Authentication Serveravec les paramètres ci-dessous.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

Vous n'envoyez pasclient_secret , vous ne pouviez pas faire confiance au client (l'utilisateur et / ou son navigateur qui essaient d'utiliser votre application). Le client peut voir l'url ou le script java et trouver client_secrectfacilement votre fichier. C'est pourquoi vous avez besoin d'une autre étape.

Vous recevez un codeet state. L' codeici est temporaryet n'est enregistré nulle part.

Ensuite, vous passez un secondappel à Instagram API(depuis votre serveur)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

Comme l'appel est effectué depuis notre serveur, nous pouvons utiliser en toute sécurité client_secret(ce qui montre comment nous sommes) avec codequels spectacles l'utilisateur a autorisé l' client_idutilisation de la ressource.

En réponse, nous aurons access_token

Alireza Fattahi
la source
1

D'un point de vue pratique (ce que j'ai compris), la principale raison d'avoir un flux de code Authz est:

  1. Prise en charge des jetons d'actualisation (accès à long terme par les applications au nom de l'utilisateur), non pris en charge implicitement: reportez-vous à: https://tools.ietf.org/html/rfc6749#section-4.2
  2. Prise en charge de la page de consentement qui est un endroit où le propriétaire de la ressource peut contrôler l'accès à fournir (type de page d'autorisation / d'autorisation que vous voyez dans google). La même chose n'est pas là en implicite. Voir section: https://tools.ietf.org/html/rfc6749#section-4.1 , point (B)

"Le serveur d'autorisation authentifie le propriétaire de la ressource (via l'agent utilisateur) et établit si le propriétaire de la ressource accorde ou refuse la demande d'accès du client"

En dehors de cela, à l'aide de jetons d'actualisation, les applications peuvent obtenir un accès à long terme aux données des utilisateurs.

dvsakgec
la source
0

Il semble y avoir deux points clés, non abordés jusqu'à présent, qui expliquent pourquoi le détour dans le type d'autorisation de code d'autorisation ajoute de la sécurité.

Petite histoire : Le type d'octroi de code d'autorisation conserve les informations sensibles de l'historique du navigateur et la transmission du jeton dépend uniquement de la protection HTTPS du serveur d'autorisation.

Version plus longue:

Dans ce qui suit, je m'en tiendrai à la terminologie OAuth 2 définie dans la RFC (c'est une lecture rapide): serveur de ressources , client , serveur d'autorisation , propriétaire de la ressource .

Imaginez que vous souhaitiez qu'une application tierce (= client) accède à certaines données de votre compte Google (= serveur de ressources). Supposons simplement que Google utilise OAuth 2. Vous êtes le propriétaire de la ressource du compte Google, mais vous exploitez actuellement l'application tierce.

Tout d'abord, le client ouvre un navigateur pour vous envoyer vers l'URL sécurisée du serveur d'autorisation Google. Ensuite, vous approuvez la demande d'accès et le serveur d'autorisation vous renvoie à l'URL de redirection précédemment donnée par le client, avec le code d'autorisation dans la chaîne de requête. Passons maintenant aux deux points clés:

  1. L'URL de cette redirection se retrouve dans l'historique du navigateur . Nous ne voulons donc pas ici d'un jeton d'accès directement utilisable de longue durée. Le code d'autorisation de courte durée est moins dangereux dans l'histoire. Notez que le type de subvention implicite ne met le jeton dans l'histoire.
  2. La sécurité de cette redirection dépend du certificat HTTPS du client , pas du certificat de Google. Nous obtenons donc la sécurité de transmission du client comme vecteur d'attaque supplémentaire (pour que cela soit inévitable, le client doit être non JavaScript. Sinon, nous pourrions transmettre le code d'autorisation via l'URL de fragment, où le code ne passerait pas par le réseau. Cela peut être la raison pour laquelle Grant implicite type, ce qui fait utiliser une URL de fragment, utilisé à recommander pour les clients JavaScript, même si ce n'est plus ainsi.)

Avec le type d'autorisation de code d'autorisation, le jeton est finalement obtenu par un appel du client au serveur d'autorisation, où la sécurité de la transmission dépend uniquement du serveur d'autorisation et non du client.

Carsten Führmann
la source