OAuth 2.0 - Le bon, le mauvais et le truand

Dans un monde dominé par les médias sociaux, il est difficile de ne pas rencontrer une application client permettant d'accéder à des ressources restreintes sur un autre serveur. Par exemple, vous avez peut-être utilisé une application Web (telle que le NY Times) pour partager un fichier. article de nouvelles intéressant sur votre mur Facebook ou tweet à ce sujet. Ou bien, vous avez peut-être utilisé l'application iPhone de Quora qui accède à votre profil Facebook ou Google+ et personnalise les résultats en fonction de vos données de profil, par exemple en suggérant d'ajouter / inviter d'autres utilisateurs à Quora, en fonction de votre liste d'amis. La question est de savoir comment ces applications peuvent accéder à vos comptes Facebook, Twitter ou Google+ et comment peuvent-elles accéder à vos données confidentielles? Avant de pouvoir le faire, ils doivent présenter au serveur de ressources des informations d'identification et des autorisations d'accès..


Introduction à OAuth 2.0

OAuth est souvent décrit comme une clé de service pour le Web..

Maintenant, ce serait vraiment pas cool partager vos informations d'identification Facebook ou Google avec toute application client tierce qui n'a besoin que de connaître vos amis, car elle donne non seulement à l'application un accès illimité et indésirable à votre compte, mais elle présente également la faiblesse inhérente liée aux mots de passe. C'est ici qu'OAuth entre en jeu, car il décrit un cadre d'autorisation de délégation d'accès / autorisation qui peut être utilisé sans qu'il soit nécessaire de partager des mots de passe. Pour cette raison, OAuth est souvent décrit comme une clé de voiturier pour le Web. Cela peut être considéré comme une clé spéciale qui permet d’accéder à des fonctions limitées pendant une période limitée sans céder le contrôle total, tout comme la clé du voiturier d’une voiture permet au préposé au stationnement de conduire la voiture sur une courte distance. accès au coffre et au téléphone portable à bord.

Cependant, OAuth n'est pas un nouveau concept, mais une standardisation et une sagesse combinée de nombreux protocoles bien établis. Il convient également de noter que OAuth ne se limite pas aux applications de médias sociaux, il fournit un moyen standardisé de partager des informations en toute sécurité entre divers types d’applications exposant leurs API à d’autres applications. OAuth 2.0 a une prose complètement nouvelle et n'est pas rétrocompatible avec les spécifications de son prédécesseur. Cela dit, il serait bon de commencer par aborder un vocabulaire de base sur OAuth2.0 avant d’entrer dans les détails..

  • Propriétaire de la ressource : Une entité capable d’accorder l’accès à une ressource protégée. La plupart du temps, c'est un utilisateur final.
  • Client : Application effectuant des demandes de ressources protégées pour le compte du propriétaire de la ressource et avec son autorisation. Il peut s'agir d'une application serveur, mobile (native) ou de bureau.
  • Serveur de ressources : Le serveur hébergeant les ressources protégées, capable d'accepter et de répondre aux demandes de ressources protégées.
  • Serveur d'autorisation : Le serveur qui délivre l'accès accorde des autorisations / jetons au client après l'authentification réussie du propriétaire de la ressource et l'obtention de l'autorisation.
  • Jeton d'accès : Les jetons d'accès sont des informations d'identification présentées par le client au serveur de ressources pour accéder aux ressources protégées. Il s'agit normalement d'une chaîne composée d'une étendue, d'une durée de vie et d'autres attributs d'accès spécifiques. Elle peut auto-contenir les informations d'autorisation de manière vérifiable..
  • Refresh Token Remarque: Bien que cela ne soit pas obligatoire par la spécification, les jetons d'accès ont idéalement un délai d'expiration qui peut durer de quelques minutes à plusieurs heures. Une fois qu'un jeton d'accès a expiré, le client peut demander au serveur d'autorisation d'émettre un nouveau jeton d'accès à l'aide du jeton d'actualisation émis par le serveur d'autorisation..

Quel est le problème avec OAuth 1.0?

L'inconvénient majeur d'OAuth 1.0 était la complexité inhérente à la mise en œuvre de la spécification.

Rien vraiment! Twitter fonctionne toujours parfaitement avec OAuth 1.0 et vient de commencer à supporter une petite partie de la spécification 2.0. OAuth 1.0 était une spécification bien pensée et elle permettait l'échange d'informations secrètes en toute sécurité sans la surcharge imposée par SSL. La raison pour laquelle nous avions besoin d'une refonte était principalement basée sur la complexité de la mise en œuvre de la spécification. Dans certains domaines, OAuth 1.0 n'a pas réussi à impressionner:

  • Signer chaque demande : Demander au client de générer des signatures sur chaque demande d'API et de les valider sur le serveur chaque fois qu'une demande est reçue constitue un inconvénient majeur pour les développeurs, car ils devaient analyser, coder et trier les paramètres avant d'effectuer une demande. OAuth 2.0 a supprimé cette complexité en envoyant simplement les jetons via SSL, résolvant le même problème au niveau du réseau. Aucune signature n'est requise avec OAuth 2.0.
  • Adressage d'applications natives : Avec l'évolution des applications natives pour les périphériques mobiles, le flux Web d'OAuth 1.0 semblait inefficace, rendant obligatoire l'utilisation d'agents utilisateur, tels qu'un navigateur Web. OAuth 2.0 a pris en charge davantage de flux spécifiquement adaptés aux applications natives.
  • Séparation claire des rôles : OAuth 2.0 fournit la séparation bien nécessaire des rôles du serveur d'autorisation authentifiant et autorisant le client et de celle du serveur de ressources gérant les appels d'API pour accéder aux ressources restreintes.

OAuth 2.0 en profondeur

Avant d'initier le protocole, le client doit s'inscrire auprès du serveur d'autorisation en fournissant son type de client, son URL de redirection (à l'endroit où il souhaite que le serveur d'autorisation se redirige après que le propriétaire de la ressource ait accordé ou refusé l'accès) et toute autre information requise par le serveur. et à son tour, un identifiant client (client_id) et un secret client (client_secret) sont attribués. Ce processus s'appelle l'enregistrement du client. Après l'enregistrement, le client peut adopter l'un des flux suivants pour interagir avec le serveur..

Divers flux OAuth

OAuth 2.0 apporte environ cinq nouveaux flux à la table et donne aux développeurs la possibilité de les implémenter, en fonction du type de client impliqué:

  • Flux utilisateur-agent : Convient aux clients généralement implémentés dans des agents utilisateurs (par exemple, des clients s'exécutant dans un navigateur Web) à l'aide d'un langage de script tel que JavaScript. Principalement utilisé par les applications natives pour mobiles ou ordinateurs de bureau, exploitant le navigateur intégré ou externe en tant qu'agent d'utilisateur pour l'autorisation. Subvention implicite autorisation.
  • Flux de serveur Web : Cela fait usage de la Code d'autorisation grant est un flux basé sur la redirection qui nécessite une interaction avec l'agent utilisateur de l'utilisateur final. Ainsi, il convient mieux aux clients qui font partie d'applications basées sur un serveur Web et qui sont généralement accessibles via un navigateur Web..
  • Nom d'utilisateur et mot de passe : Utilisé uniquement lorsqu'il existe une confiance élevée entre le client et le propriétaire de la ressource et lorsque d'autres flux ne sont pas viables, car cela implique le transfert des informations d'identification du propriétaire de la ressource. Des exemples de clients peuvent être un système d'exploitation de périphérique ou une application hautement privilégiée. Cela peut également être utilisé pour migrer des clients existants à l'aide de schémas HTTP Basic ou d'authentification Digest vers OAuth en convertissant les informations d'identification stockées en un jeton d'accès..
  • Flux d'assertion : Votre client peut présenter une assertion telle qu'une assertion SAML au serveur d'autorisation en échange d'un jeton d'accès.
  • Flux d'informations d'identification du client : OAuth est principalement utilisé pour l'accès délégué, mais il existe des cas où le client est propriétaire de la ressource ou a déjà obtenu l'accès délégué en dehors d'un flux OAuth typique. Ici, il vous suffit d'échanger les informations d'identification du client contre un jeton d'accès..

Discuter en détail de chaque flux sortirait du cadre de cet article et je recommanderais plutôt de lire les spécifications pour des informations détaillées sur les flux. Mais pour avoir une idée de ce qui se passe, approfondissons l'un des flux les plus utilisés et les plus pris en charge: le flux de serveur Web..

Le flux de serveur Web

S'agissant d'un flux basé sur la redirection, le client doit pouvoir interagir avec l'agent utilisateur du propriétaire de la ressource (qui est dans la plupart des cas un navigateur Web) et est donc généralement adapté à une application Web. Le diagramme ci-dessous est une vue à vol d'oiseau de la façon dont l'utilisateur final (ou le propriétaire de la ressource) utilise l'application cliente (application basée sur un serveur Web dans ce cas) pour s'authentifier et s'autoriser avec le serveur d'autorisation, afin d'accéder aux ressources protégées. par le serveur de ressources.


Authentifier et autoriser le client

Le client, au nom du propriétaire de la ressource, initie le flux en le redirigeant vers le noeud final d'autorisation avec un paramètre response_type: code, un identifiant client obtenu lors de l'inscription du client, une URL de redirection, une étendue demandée (facultatif) et un état local (le cas échéant). Pour avoir une idée de la façon dont cela fonctionne réellement, voici une capture d'écran de ce à quoi une demande / réponse typique ressemblerait:


Cela présente normalement au propriétaire de la ressource une interface Web, où le propriétaire peut s'authentifier et vérifier quelles autorisations toutes les autorisations que l'application client peut utiliser pour le compte du propriétaire.


En supposant que le propriétaire de la ressource accorde l'accès au client, le serveur d'autorisation redirige l'agent utilisateur vers le client en utilisant l'URL de redirection fournie précédemment, ainsi que le code d'autorisation indiqué dans la réponse ci-dessous..


Code d'autorisation d'échange pour les jetons

Le client alors des postes à un autre noeud final d'autorisation et envoie le code d'autorisation reçu à l'étape précédente, ainsi que l'URL de redirection, son identifiant client et son secret, obtenus lors de l'enregistrement du client, et un paramètre grant_type doit être défini comme suit: Code d'autorisation.


Le serveur valide ensuite le code d'autorisation et vérifie que l'URL de redirection est identique à celle de l'étape précédente. En cas de succès, le serveur répond avec un jeton d'accès et éventuellement un jeton d'actualisation..


Demander des ressources restreintes à l'aide de jetons d'accès

Le client peut maintenant utiliser les API fournies par l'implémentation et peut interroger le serveur de ressources sur une ressource restreinte en transmettant le jeton d'accès dans l'en-tête Authorization de la demande. Un exemple de requête CURL à l'API Google Blogger pour obtenir un blog, compte tenu de son identifiant, ressemblerait à ceci:

 $ curl https://www.googleapis.com/blogger/v3/blogs/5223788876950011016 -H 'Autorisation: OAuth ya29.AHES6ZRTj1GNxAby81Es-p_YPWWNBAFRvBYVsYj2JfJHH'

Notez que nous avons ajouté le jeton d'accès en tant qu'en-tête d'autorisation dans la demande et que nous l'avons également échappé en l'incluant entre guillemets simples, car le jeton peut contenir des caractères spéciaux. N'oubliez pas que l'échappement du jeton d'accès n'est requis que lorsque vous utilisez curl. Il en résulte l'envoi de la requête suivante:


Le serveur de ressources vérifie ensuite les informations d'identification transmises (jeton d'accès) et, en cas de succès, répond avec les informations demandées..


Ces exemples sont une gracieuseté de OAuth2.0 Playground et sont typiques de la façon dont Google met en œuvre les spécifications. Des différences peuvent être observées lorsque vous essayez le même flux avec d’autres fournisseurs (comme Facebook ou Salesforce) et c’est là que les problèmes d’interopérabilité se glissent, ce dont nous parlerons un peu plus tard..

Actualisation du jeton d'accès

Bien que cela ne soit pas imposé par la spécification, les jetons d’accès sont généralement de courte durée et ont une date d’expiration. Ainsi, lorsqu'un jeton d'accès a expiré, le client envoie le jeton d'actualisation au serveur d'autorisation, avec son identificateur client et son secret, ainsi qu'un paramètre grant_type en tant que refresh_token.


Le serveur d'autorisation répond ensuite avec la nouvelle valeur du jeton d'accès..


Bien qu'il existe un mécanisme permettant de révoquer le jeton d'actualisation émis, mais normalement, le jeton d'actualisation est éternel et doit être protégé et traité comme une valeur secrète..


Quel est le problème avec OAuth 2.0?

Les bonnes choses

Selon le taux d’adoption, OAuth 2.0 est définitivement une amélioration par rapport à son prédécesseur arcanique. Les instances de communauté de développeurs qui faiblissent lors de l’implémentation des signatures 1.0 ne sont pas inconnues. OAuth 2.0 fournit également plusieurs nouveaux types de subvention, qui peuvent être utilisés pour prendre en charge de nombreux cas d'utilisation, tels que les applications natives, mais l'USP de cette spécification est sa simplicité par rapport à la version précédente..

Les mauvaises parties

La spécification comporte quelques détails non structurés, car elle ne permet pas de définir correctement quelques composants requis ou ne les laisse pas au choix des implémentations, telles que:

Les bouts lâches dans la spécification OAuth 2.0 sont susceptibles de produire une large gamme d'implémentations non interopérables.

  • L'interopérabilité: L'ajout de trop de points d'extension dans la spécification a entraîné des implémentations incompatibles entre elles. Cela signifie que vous ne pouvez pas espérer écrire un morceau de code générique qui utilise Endpoint Discovery pour connaître les points de terminaison fournis par les différentes implémentations et interagir avec celles-ci, vous devrez plutôt écrire des morceaux de code distincts pour Facebook, Google, Salesforce, etc. Même la spec admet cet échec comme un disclaimer.
  • Jetons à vie courte: La spécification n'impose pas la durée de vie et la portée des jetons émis. L'implémentation est libre de faire vivre un jeton pour toujours. Bien que la plupart des implémentations nous fournissent des jetons d'accès de courte durée et un jeton d'actualisation, qui peuvent être utilisés pour obtenir un nouveau jeton d'accès..
  • Sécurité: La spécification ne fait que "recommander" l'utilisation de SSL / TLS lors de l'envoi des jetons en texte clair via le fil. Bien que chaque mise en œuvre majeure ait imposé l'obligation de disposer de points de terminaison d'autorisation sécurisés, le client doit disposer d'une URL de redirection sécurisée. Dans le cas contraire, il sera beaucoup trop facile pour un attaquant d'écouter la communication et de déchiffrer les jetons..

La gueule laide

Il a fallu environ 31 versions préliminaires à l'IETF et la démission du principal auteur / développeur Eran Hammer du comité pour enfin publier la spécification. Eran a déclenché une controverse en appelant la spécification "un mauvais protocole et un cas de mort par mille coupures". Selon lui, l'utilisation de jetons au porteur (envoi de jetons via SSL sans les signer ou toute autre vérification) sur l'utilisateur de signatures (ou de jetons MAC), utilisée dans OAuth 1.0 pour signer la demande, était un mauvais coup et un résultat de la division des intérêts entre le Web et les entreprises.


Remarques conclusives

La spécification laisse sûrement de nombreux points d'extension ouverts, ce qui aboutit à des implémentations qui introduisent leurs propres paramètres, en plus de ce que la spécification définit déjà, et veille à ce que les implémentations de différents fournisseurs ne puissent pas interopérer les unes avec les autres. Mais avec la popularité et le taux d’adoption de ce framework, avec tous les grands acteurs de la ville (Google, Twitter, Facebook, Salesforce, Foursquare, Github, etc.) en le mettant en œuvre et en le peaufinant comme il leur convient, OAuth est loin d’être un échec . En fait, toute application Web qui envisage d'exposer ses API à d'autres applications Web doit prendre en charge une forme d'authentification et d'autorisation et OAuth convient parfaitement..

Pour en savoir plus

  • OAuth et le chemin de l'enfer
  • OAuth - Une introduction
  • RFC 5849 - Spécification OAuth1.0
  • RFC 6749 - Spécification OAuth2.0