À quoi sert le type d'autorisation d'autorisation implicite dans OAuth 2?

254

Je ne sais pas si j'ai juste une sorte d'angle mort ou quoi, mais j'ai lu la spécification OAuth 2 à plusieurs reprises et parcouru les archives de la liste de diffusion, et je n'ai pas encore trouvé une bonne explication de la raison pour laquelle la subvention implicite un flux permettant d'obtenir des jetons d'accès a été développé. Comparé à l'autorisation de code d'autorisation, il semble abandonner l'authentification du client sans raison très convaincante. Comment est-ce "optimisé pour les clients implémentés dans un navigateur utilisant un langage de script" (pour citer la spécification)?

Les deux flux démarrent de la même manière (source: http://tools.ietf.org/html/draft-ietf-oauth-v2-22 ):

  1. Le client lance le flux en dirigeant l'agent utilisateur du propriétaire de la ressource vers le point de terminaison d'autorisation.
  2. 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.
  3. En supposant que le propriétaire de la ressource accorde l'accès, le serveur d'autorisation redirige l'agent utilisateur vers le client à l'aide de l'URI de redirection fourni précédemment (dans la demande ou lors de l'inscription du client).
    • L'URI de redirection inclut un code d'autorisation (Flux de code d'autorisation)
    • L'URI de redirection inclut le jeton d'accès dans le fragment URI (flux implicite)

Voici où les flux se divisent. Dans les deux cas, l'URI de redirection à ce stade est vers un point de terminaison hébergé par le client:

  • Dans le flux de code d'autorisation, lorsque l'agent utilisateur atteint ce point de terminaison avec le code d'autorisation dans l'URI, le code à ce point de terminaison échange le code d'autorisation avec ses informations d'identification client pour un jeton d'accès qu'il peut ensuite utiliser selon les besoins. Il pourrait, par exemple, l'écrire dans une page Web à laquelle un script de la page pourrait accéder.
  • Le flux implicite ignore complètement cette étape d'authentification client et charge simplement une page Web avec le script client. Il y a une astuce mignonne ici avec le fragment d'URL qui empêche le jeton d'accès de trop circuler, mais le résultat final est essentiellement le même: le site hébergé par le client sert une page avec un script qui peut récupérer le jeton d'accès .

D'où ma question: qu'est-ce qui a été gagné ici en sautant l'étape d'authentification du client?

Dan Taflin
la source
Jetez un œil à ceci: ibm.com/developerworks/wikis/display/…
Håvard Geithus
5
Le lien dans le commentaire précédent est mort. Voici une mise à jour
AndrewR
3
J'ai lu toutes les réponses ici, mais je ne comprends toujours pas comment ne pas sécuriser un secret client privé pour obtenir un jeton d'accès. Supposons que TrustedAppDeveloper publie TrustedPopularApp qui permet aux utilisateurs de lui accorder des autorisations (par exemple, en utilisant Twitter oauth) en utilisant une autorisation implicite. Si je suis EvilAppDeveloper, qu'est-ce qui m'empêche de créer une application qui transmet TrustedPopularAppId en tant que client_id dans une demande de subvention implicite, puis d'effectuer des actions (comme spammer un flux) au nom de l'utilisateur, qui semblent maintenant provenir de TrustedPopularApp ?
adevine
Je me demande la même chose que adevine. Mais, les applications les plus probables qui nécessitent une demande de subvention implicite, n'ont pas besoin de plus d'authentification, car elles le sont toutes?
Mave le
13
@adevine Ce qui empêcherait EvilApp dans votre scénario de s'authentifier sur Twitter en tant que TrustedPopularApp, c'est qu'il ne pourrait pas recevoir les rappels de Twitter, ils seraient toujours envoyés à l'URI défini lors de l'enregistrement de l'ID client
Ivan

Réponses:

196

Voici mes pensées:

Le but du code d'authentification + jeton dans le flux de code d'autorisation est que le jeton et le secret client ne seront jamais exposés au propriétaire de la ressource car ils voyagent de serveur à serveur.

De l'autre côté, le flux d'octroi implicite est destiné aux clients qui sont entièrement implémentés à l'aide de javascript et s'exécutent dans le navigateur du propriétaire de la ressource. Vous n'avez pas besoin de code côté serveur pour utiliser ce flux. Ensuite, si tout se passe dans le navigateur du propriétaire de la ressource, il n'est plus logique d'émettre le code d'authentification et le secret client, car le jeton et le secret client seront toujours partagés avec le propriétaire de la ressource. L'inclusion de code d'authentification et de secret client rend simplement le flux plus complexe sans ajouter plus de sécurité réelle.

Donc, la réponse sur "ce qui a été gagné?" c'est la "simplicité".

Philip Peshin
la source
4
Merci. C'est un bon point que dans le flux de code d'autorisation, le propriétaire de la ressource n'a jamais besoin de voir le jeton d'accès, alors que dans les clients javascript, c'est inévitable. Cependant, le secret client peut toujours être gardé des clients javascript en utilisant le flux de code d'autorisation: après authentification et obtention d'un jeton d'accès, le code côté serveur transmettra ensuite le jeton au client javascript. Ce que je vois maintenant, cependant, c'est que le flux de subvention implicite permet la distribution de SDK javascript oauth, comme Facebook, libérant les développeurs d'avoir à écrire complètement leur propre code oauth.
Dan Taflin
3
J'ajouterais peut-être que le flux de code d'autorisation permet aux clients de stocker les jetons et de les réutiliser. Dans le flux implicite, vous n'avez pas toujours cette option et en tant que tel, le flux implicite est un choix pragmatique entre le niveau de sécurité et la commodité.
PålOliver
2
Cela ne répond qu'à la moitié, et "qu'est-ce qui a été perdu"?
EralpB
3
Je ne pense pas que ce soit une réponse complète, le flux implicite n'est pas destiné à tirer parti de la simplicité, mais à compromettre les problèmes de sécurité avec l'application côté client. Auth code, ainsi que client_idet client_secretsont utilisés pour identifier les clients de confiance qui peuvent actualiser les jetons pour une connexion à long terme et pour une "connexion hors ligne" . Cependant, dans une application côté client, il n'y a aucun moyen d'enregistrer chaque client, d'où le type de subvention implicite "simplifié" pour un accès temporaire aux informations utilisateur
Chen Xie
1
Inclure le secret client ne rend pas seulement le flux plus complexe, il le rend moins sécurisé . Le secret client n'est pas un secret s'il doit être énuméré dans le code côté client, et il serait donc exposé à Internet. Si votre ID client n'est utilisé que dans les flux implicites, ce n'est pas un problème. Mais s'il est également utilisé ailleurs dans votre plate-forme pour actualiser les jetons ou les autorisations de code d'autorisation, alors le secret correspondant exposé est un gros problème.
Ataraxia
94

Il est là pour des raisons de sécurité, pas pour des raisons de simplicité.

Vous devez considérer la différence entre l' agent utilisateur et le client :

L'agent utilisateur est le logiciel par lequel l'utilisateur ("propriétaire des ressources") communique avec d'autres parties du système (serveur d'authentification et serveur de ressources).

Le client est le logiciel qui souhaite accéder aux ressources de l'utilisateur sur le serveur de ressources.

Dans le cas d'un agent utilisateur et d'un client découplés, la subvention de code d'autorisation est logique. Par exemple, l'utilisateur utilise un navigateur Web (user-agent) pour se connecter avec son compte Facebook sur Kickstarter. Dans ce cas, le client est l'un des serveurs du Kickstarter, qui gère les connexions utilisateur. Ce serveur obtient le jeton d'accès et le jeton d'actualisation de Facebook. Ainsi ce type de client considéré comme "sécurisé", en raison d'un accès restreint, les jetons peuvent être enregistrés et Kickstarter peut accéder aux ressources des utilisateurs et même actualiser les jetons d'accès sans interaction de l'utilisateur.

Si l'agent utilisateur et le client sont couplés (par exemple application mobile native, application javascript), le workflow d'autorisation implicite peut être appliqué. Il repose sur la présence du propriétaire de la ressource (pour la saisie des informations d'identification) et ne prend pas en charge les jetons d'actualisation. Si ce client stocke le jeton d'accès pour une utilisation ultérieure, ce sera un problème de sécurité, car le jeton peut être facilement extrait par d'autres applications ou utilisateurs du client. L'absence du jeton d'actualisation est un indice supplémentaire, que cette méthode n'est pas conçue pour accéder aux ressources de l'utilisateur en l'absence de l'utilisateur.

artkoenig
la source
2
Je vois que mon navigateur s'est connecté à mon compte Google depuis des mois. Alors, est-ce que Google utilise un jeton d'accès sur le navigateur ou un jeton d'accès avec un long délai d'expiration? Quelle différence d'utilisation entre le jeton d'accès avec un long délai d'expiration et le jeton d'accès? tout autre client peut intercepter le jeton d'accès et l'utiliser lorsque le propriétaire de la ressource n'est pas présent.
Mohammad Nikravan
Je suppose que vous voulez dire la différence entre le jeton d'actualisation et le jeton d'accès avec un long délai d'expiration ? Le jeton d'actualisation ne doit pas être enregistré dans des scénarios non sécurisés, mais vous pouvez cependant enregistrer votre jeton d'accès (par exemple dans le stockage local du navigateur). La sécurité est obtenue en gardant la durée de vie de votre jeton d'accès aussi faible que possible, mais toujours confortable pour vos utilisateurs (par exemple, vous pouvez les déconnecter automatiquement après x minutes d'inactivité). Si vous utilisez des jetons d'accès longue durée, vous rendez pratiquement obsolètes les jetons d'actualisation.
artkoenig
Merci pour votre explication mais j'ai une autre confusion aussi. Je ne comprends pas pourquoi nous avons besoin du flux "Code d'autorisation". Nous pouvons atteindre le même résultat sur le serveur par flux implicite (access_token) et un jeton de rafraîchissement. Il semble que la seule considération de sécurité du flux implicite soit 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 ce jeton sur un serveur pour obtenir access_code alors que nous pouvons obtenir le même résultat avec refresh_token?
Mohammad Nikravan
"le jeton peut être facilement extrait par d'autres applications" Comment?
mvmn
@MohammadNikravan cherche la réponse dans stackoverflow.com/q/13387698/355438
Lu55
60

L'explication habituelle est que la subvention implicite est plus facile à implémenter lorsque vous utilisez un client JavaScript. Mais je pense que ce n'est pas la bonne façon de voir les choses. Si vous utilisez un client JavaScript qui demande des ressources protégées directement via XMLHttpRequest, la subvention implicite est votre seule option, bien qu'elle soit moins sécurisée. *

L'octroi du code d'autorisation offre une sécurité supplémentaire, mais il ne fonctionne que lorsque vous avez un serveur Web demandant les ressources protégées. Étant donné que le serveur Web peut stocker le jeton d'accès, vous courez moins de risques que le jeton d'accès soit exposé à Internet et vous pouvez émettre un jeton qui dure longtemps. Et comme le serveur Web est fiable, il peut recevoir un "jeton d'actualisation", afin qu'il puisse obtenir un nouveau jeton d'accès lorsque l'ancien expire.

Mais - et c'est un point qui est facile à manquer - la sécurité du flux de code d'autorisation ne fonctionne que si le serveur Web est protégé par une session, qui est établie avec l'authentification des utilisateurs (connexion). Sans session, un utilisateur non fiable pourrait simplement faire des demandes au serveur Web, en utilisant le client_id, et ce serait la même chose que si l'utilisateur avait le jeton d'accès. L'ajout d'une session signifie que seul un utilisateur authentifié peut accéder aux ressources protégées. Le client_id est juste "l'identité" de la webapp JS, pas l'authentification de ladite webapp.

Cela signifie également que vous pouvez mettre fin à la session avant l'expiration du jeton OAuth. Il n'existe aucun moyen standard d'invalider un jeton d'accès. Mais si votre session expire, le jeton d'accès est inutile, car personne ne le sait sauf le serveur web. Si un utilisateur non fiable accède à votre clé de session, il ne pourra accéder aux ressources protégées que tant que la session sera valide.

S'il n'y a pas de serveur Web, vous devez utiliser la subvention implicite. Mais cela signifie que le jeton d'accès est exposé à Internet. Si un utilisateur non fiable y accède, il peut l'utiliser jusqu'à son expiration. Cela signifie qu'ils y auront accès plus longtemps qu'avec une autorisation de code d'autorisation. Vous pouvez donc envisager de faire expirer le jeton plus tôt et éviter de donner accès à des ressources plus sensibles.

* EDIT: Plus récemment, les gens recommandent d'éviter d'utiliser la subvention implicite, même sur les applications Web sans serveur. Au lieu de cela, vous pouvez utiliser l'autorisation de code d'autorisation configurée avec un secret vide, avec PKCE. L'accord de code d'authentification évite de stocker le jeton d'accès dans l'historique de votre navigateur, et PKCE évite de l'exposer si quelqu'un détourne l'URL de redirection pour voler le code d'authentification. Dans ce cas, vous auriez besoin du serveur pour éviter de retourner un jeton d'actualisation, car votre client ne peut probablement pas le stocker en toute sécurité. Et il devrait émettre un jeton d'accès avec les mêmes limitations mentionnées ci-dessus.

JW.
la source
21

Cela se résume à: Si un utilisateur exécute une application Web (JavaScript) basée sur un navigateur ou "publique", sans composant côté serveur, alors l'utilisateur fait implicitement confiance à l'application (et au navigateur où elle s'exécute, potentiellement avec un autre navigateur). basées sur les applications ...).

Il n'y a pas de serveur distant tiers, uniquement le serveur de ressources. Il n'y a aucun avantage à un code d'autorisation, car il n'y a pas d' autre agent que le navigateur agissant au nom de l'utilisateur. Les informations d'identification du client ne présentent aucun avantage pour la même raison. ( Tout client peut tenter d'utiliser ce flux.)

Les implications pour la sécurité sont cependant importantes. Sur http://tools.ietf.org/html/rfc6749#section-10.3 :

Lorsque vous utilisez le type d'autorisation implicite, le jeton d'accès est transmis dans le fragment URI, ce qui peut l'exposer à des parties non autorisées.

Sur http://tools.ietf.org/html/rfc6749#section-10.16 :

Un propriétaire de ressource peut volontairement déléguer l'accès à une ressource en accordant un jeton d'accès au client malveillant d'un attaquant. Cela peut être dû au phishing ou à un autre prétexte ...

Volonté
la source
qu'entendez-vous par application Web «publique» (JavaScript) sans composant côté serveur? Comment peut-il y avoir une application web sans serveur?
Zammy Page
2
@ZammyPage, ce serait ce qu'on appelle souvent une application de page unique (SPA). L'intégralité de l'application est servie à partir d'une ressource statique. Javascript dans l'application accède ensuite dynamiquement à toutes les ressources dont elle a besoin, sur tous les serveurs de ressources auxquels elle peut accéder. Il n'y a pas de serveur qui génère le contenu du client: le javascript du client modifie le DOM selon les besoins pour représenter les ressources auxquelles il a accédé.
Elroy Flynn
13

Je ne suis pas sûr d'avoir bien compris la réponse et le commentaire de Dan. Il me semble que la réponse a énoncé certains faits, mais elle précise exactement ce que OP a demandé. Si je comprends bien, le principal avantage du flux de subventions implicites est qu'un client comme l'application JS (par exemple l'extension Chrome) n'a pas à divulguer le secret du client.

Dan Taflin a déclaré:

... dans le flux de code d'autorisation, le propriétaire de la ressource n'a jamais besoin de voir le jeton d'accès, alors que dans les clients javascript, c'est inévitable. Cependant, le secret client peut toujours être gardé des clients javascript en utilisant le flux de code d'autorisation.

Je vous ai peut-être mal compris, mais le client (application JS dans ce cas) doit transmettre les informations d'identification du client (clé client et secret) au serveur de ressources dans le flux de code d'autorisation, non? Le secret client ne peut pas être «conservé de JS».

tzuchien.chiu
la source
6
Je me rends compte que c'est une vieille question, mais c'est une meilleure réponse que celle acceptée. La raison pour laquelle la subvention implicite existe est qu'un client javascript ne peut pas garder de secret et ne peut donc pas être authentifié. Le serveur d'autorisation doit donc se fier uniquement à l'enregistrement de l'URI de redirection et à l'agent utilisateur pour des raisons de sécurité. Vous transmettez les jetons d'autorisation uniquement à l'agent utilisateur, et uniquement à un uri de redirection spécifique, empêchant théoriquement l'interception (car un utilisateur malveillant qui ne possède pas le domaine de l'URI de redirection ne peut pas exécuter de code dans l'agent utilisateur à cet uri).
grégats
En effet, la réponse acceptée m'a dérouté. Me fait penser que j'ai mal compris ce qu'est le client_secret! Cette réponse et le commentaire ci-dessus sont parfaits.
Salsepareille du
9

Tandis que qu'Implicit Grant ait été conçu pour prendre en charge les applications qui ne pouvaient pas protéger un secret client, y compris les applications JavaScript côté client, certains fournisseurs implémentent une alternative utilisant le code d'autorisation sans secret client à la place. L'OAuth 2.0 IETF RFC-6749 a été publié en 2012 et les recommandations actuelles, certaines discussions récentes datent de 2017.

La discussion de 2017 sur la liste de diffusion IETF OAuth est disponible auprès de ces implémenteurs:

En savoir plus ici:

Implicite était précédemment recommandé pour les clients sans secret, mais il a été remplacé par l'utilisation de l'autorisation de code d'autorisation sans secret.

...

Auparavant, il était recommandé que les applications basées sur un navigateur utilisent le flux "implicite", qui renvoie immédiatement un jeton d'accès et ne comporte pas d'étape d'échange de jetons. Depuis que la spécification a été rédigée à l'origine, les meilleures pratiques de l'industrie ont changé pour recommander que le flux de code d'autorisation soit utilisé sans le secret du client. Cela offre plus d'occasions de créer un flux sécurisé, comme l'utilisation du paramètre d'état. Références: Redhat , Deutsche Telekom , Smart Health IT .

Le passage au code d'authentification sans secret client à partir de la subvention implicite est également mentionné pour les applications mobiles ici:

Grokify
la source
Je pense que vous voulez être prudent avec cette recommandation. Cela a été recommandé dans les instructions pour les applications natives plutôt que pour les spas. Malheureusement, il n'y a pas de bons conseils sur les SPA comme documenté dans de nombreuses discussions en ligne, forums et même liste de diffusion oauth-wg.
Tom
La recommandation de passer au code d'authentification sans secret de la subvention implicite est une recommandation pour les SPA et les applications mobiles, mais mon extrait ci-dessus est spécifique aux SPA. L'article référencé utilise un texte similaire pour les SPA et les applications mobiles, mais avec la langue «applications basées sur navigateur» «applications mobiles et natives» dans le texte respectif. De plus, les références pour Redhat, DT, Smart Health IT sont spécifiques aux SPA et ne sont pas incluses dans la note pour les applications mobiles. J'ai ajouté un lien profond vers les SPA dans la réponse pour le rendre plus facile à trouver. Veuillez publier des liens vers les discussions que vous mentionnez.
Grokify
Une discussion assez récente (2018) oauth-wg peut être trouvée ici ietf.org/mail-archive/web/oauth/current/msg18020.html . RFC 8252 est pour les applications natives comme le titre le suggère "OAuth 2.0 pour les applications natives". Les références à Redhat, DT, Smart Health IT sont des réponses à une discussion de liste de diffusion, pas un rfc, un brouillon de travail, etc ...
Tom
3

en plus des autres réponses, il est également important de se rendre compte que le profil implicite permet un flux de canal avant uniquement par opposition au flux de code d'autorisation qui nécessite un rappel au serveur d'autorisation; cela devient évident dans OpenID Connect qui est un protocole SSO construit au-dessus d'Auth 2.0 où le flux implicite ressemble à la liaison SAML POST assez populaire et le flux de code d'autorisation ressemble à la liaison SAML Artifact moins largement déployée

Hans Z.
la source
3

Dans le flux implicite, si le navigateur de l'utilisateur est corrompu (extension malveillante / virus), la corruption accède aux ressources de l'utilisateur et peut faire le mal.

Dans le flux d'authentification, la corruption ne peut pas car elle ne connaît pas le secret du client.

Rythme
la source
2

https://tools.ietf.org/html/rfc6749#page-8

Implicite

L'octroi implicite est un flux de code d'autorisation simplifié optimisé pour les clients implémentés dans un navigateur utilisant un langage de script tel que JavaScript. Dans le flux implicite, au lieu d'émettre au client un code d'autorisation, le client reçoit directement un jeton d'accès (à la suite de l'autorisation du propriétaire de la ressource). Le type d'autorisation est implicite, car aucune information d'identification intermédiaire (comme un code d'autorisation) n'est émise (et utilisée plus tard pour obtenir un jeton d'accès).

Lors de l'émission d'un jeton d'accès pendant le flux d'octroi implicite, le
serveur d'autorisation n'authentifie pas le client. Dans certains
cas, l'identité du client peut être vérifiée via l'URI de redirection
utilisé pour fournir le jeton d'accès au client. Le jeton d'accès peut être exposé au propriétaire de la ressource ou à d'autres applications ayant accès à l'agent utilisateur du propriétaire de la ressource.

Les subventions implicites améliorent la réactivité et l'efficacité de certains
clients (comme un client implémenté en tant qu'application dans le navigateur),
car cela réduit le nombre d'aller-retour nécessaires pour obtenir un
jeton d'accès.

Rzv Razvan
la source
1

Je pense que Will Cain a répondu à cette question en disant: "Il n'y a aucun avantage pour les informations d'identification du client pour la même raison. (Tout client peut essayer d'utiliser ce flux.)" Considérez également que le redirect_uri pour le flux implicite peut être "localhost" - pas de rappel est créé à partir du serveur d'autorisation pour le flux implicite. Comme il n'y a aucun moyen de faire confiance au client, l'utilisateur devrait approuver la libération des revendications utilisateur.

Mike Schwartz
la source
1

La subvention implicite permet d'obtenir des jetons du point de terminaison d'autorisation avec a GET. Cela signifie que le serveur d'autorisation n'a pas à prendre en charge CORS.

Si ce n'est pas un problème et qu'aucun autre problème lié au serveur d'autorisation n'a été inflexible (par exemple, les jetons d'actualisation ne sont pas facultatifs, pour une raison quelconque), le flux de code d'autorisation est le préféré, même pour les clients publics, selon les tendances récentes de l'industrie. et au moins cette instance (actuelle) d'un projet officiel .

Historiquement, il y avait d'autres raisons pour implémenter le flux implicite, mais il semble qu'elles soient actuellement contrebalancées par les avantages de sécurité fournis par le code d'autorisation, notamment:

  • possibilité de fournir et d'utiliser les jetons sur un canal de retour pour les clients confidentiels
  • ne pas exposer les jetons dans l'historique du navigateur pour les clients publics
  • interrompre un flux non autorisé avant l'émission des jetons - avec PKCE , pour "toutes sortes de clients OAuth"
ko la
la source
0

Je viens de faire face à un article sur OAuth 2.0. L'auteur indique que la raison du flux implicite est que les applications JS étaient très limitées dans leurs demandes:

si vous vous demandez pourquoi le type implicite a été inclus dans OAuth 2.0, l'explication est simple: même politique d'origine. À l'époque, les applications frontales n'étaient pas autorisées à envoyer des demandes à différents hôtes pour obtenir le jeton d'accès à l'aide de code. Aujourd'hui, nous avons CORS (Cross-Origin Resource Sharing).

https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611

Lu55
la source