web-dev-qa-db-fra.com

Pourquoi OAuth v2 a-t-il des jetons d'accès et de rafraîchissement?

La section 4.2 du projet de protocole OAuth 2.0 indique qu'un serveur d'autorisation peut renvoyer un access_token (utilisé pour s'authentifier à l'aide d'une ressource) ainsi qu'un refresh_token, qui est utilisé uniquement pour créer un nouveau access_token:

https://tools.ietf.org/html/rfc6749#section-4.2

Pourquoi avoir les deux? Pourquoi ne pas simplement laisser le access_token durer aussi longtemps que le refresh_token et ne pas avoir un refresh_token?

581
dave mankoff

L'idée des jetons d'actualisation est que, si un jeton d'accès est compromis, car l'attaque est de courte durée, l'attaquant dispose d'une fenêtre limitée pour en abuser.

Les jetons d'actualisation, s'ils sont compromis, sont inutiles car l'attaquant a besoin de l'ID et du secret du client en plus du jeton d'actualisation pour pouvoir obtenir un jeton d'accès.

Ceci dit , car chaque appel à la fois au serveur d'autorisation et au serveur de ressources est effectué via SSL - y compris l'ID et le secret du client d'origine lorsqu'ils demandent le jetons d'accès/d'actualisation - Je ne suis pas sûr de la manière dont le jeton d'accès est plus "compromis" que le jeton d'actualisation de longue durée et la combinaison clientid/secret.

Ceci est bien sûr différent des implémentations dans lesquelles vous ne contrôlez pas à la fois les serveurs d'autorisation et de ressources.

Voici un bon fil parlant des utilisations des jetons d'actualisation: Archives OAuth .

Une citation de ce qui précède parle des objectifs de sécurité du jeton d'actualisation:

Actualiser les jetons ... atténue le risque de fuite de longue durée de type access_token (paramètre de requête dans un fichier journal sur un serveur de ressources non sécurisé, une application serveur de ressources bêta ou mal codée, le client JS SDK sur un site autre que https qui place access_token dans une cookie, etc)

416
catchdave

Le lien vers la discussion, fourni par Catchdave, comporte un autre point valide(lien mort, original) réalisé par Dick Hardt, qui mérite à mon sens d'être mentionné ici, en plus de ce qui a été écrit ci-dessus:

Mon souvenir des jetons d'actualisation concernait la sécurité et la révocation. <...>

révocation: si le jeton d'accès est autonome, l'autorisation peut être révoquée en n'émettant pas de nouveaux jetons d'accès. Une ressource n'a pas besoin d'interroger le serveur d'autorisation pour savoir si le jeton d'accès est valide. Cela simplifie la validation du jeton d'accès et facilite la mise à l'échelle et la prise en charge de plusieurs serveurs d'autorisation. Il existe une fenêtre de temps pendant laquelle un jeton d'accès est valide, mais l'autorisation est révoquée.

En effet, dans les cas où le serveur de ressources et le serveur d'autorisations sont la même entité et où la connexion entre l'utilisateur et l'un ou l'autre est (généralement) également sécurisée, il est peu judicieux de conserver le jeton d'actualisation séparé du jeton d'accès.

Bien que, comme indiqué dans la citation, un autre rôle des jetons d'actualisation consiste à s'assurer que le jeton d'accès peut être révoqué à tout moment par l'utilisateur (via l'interface Web dans leurs profils, par exemple) tout en maintenant le système évolutif. .

Généralement, les jetons peuvent être des identifiants aléatoires pointant vers un enregistrement spécifique dans la base de données du serveur ou contenir toutes les informations en eux-mêmes (ces informations doivent bien sûr être signées, avec MAC , par exemple. ).

Fonctionnement du système avec des jetons d'accès de longue durée

Le serveur permet au client d'accéder aux données de l'utilisateur dans un ensemble prédéfini d'étendues en émettant un jeton. Comme nous voulons garder le jeton révocable, nous devons stocker dans la base de données le jeton ainsi que l'indicateur "révoqué" défini ou non défini (sinon, comment procéder avec un jeton autonome?) La base de données peut contenir autant que len(users) x len(registered clients) x len(scopes combination) enregistre. Chaque demande d'API doit alors atteindre la base de données. Bien qu'il soit relativement simple de poser des requêtes à une telle base de données exécutant O (1), le point de défaillance unique lui-même peut avoir un impact négatif sur l'évolutivité et les performances du système.

Fonctionnement du système avec un jeton d'actualisation de longue durée et un jeton d'accès de courte durée

Ici, nous émettons deux clés: un jeton d'actualisation aléatoire avec l'enregistrement correspondant dans la base de données et un jeton d'accès autonome signé, contenant entre autres le champ d'horodatage d'expiration.

Le jeton d'accès étant autonome, nous n'avons pas besoin de consulter la base de données pour en vérifier la validité. Tout ce que nous avons à faire est de décoder le jeton et de valider la signature et l’horodatage.

Néanmoins, nous devons toujours conserver la base de données des jetons d'actualisation, mais le nombre de demandes adressées à cette base de données est généralement défini par la durée de vie du jeton d'accès (plus la durée de vie est longue, plus le taux d'accès est faible).

Afin de révoquer l'accès du client à un utilisateur particulier, nous devons marquer le jeton d'actualisation correspondant comme "révoqué" (ou le supprimer complètement) et cesser d'émettre de nouveaux jetons d'accès. Il est toutefois évident qu'il existe une fenêtre au cours de laquelle le jeton d'actualisation a été révoqué, mais son jeton d'accès peut toujours être valide.

Compromis

Les jetons de rafraîchissement éliminent partiellement le SPoF (point unique de défaillance) de la base de données de jetons d'accès, mais présentent néanmoins des inconvénients évidents.

  1. La fenêtre". Un délai entre les événements "l'utilisateur révoque l'accès" et "il est garanti que l'accès est révoqué".

  2. La complication de la logique client.

    sans jeton d'actualisation

    • envoyer une demande d'API avec un jeton d'accès
    • si le jeton d'accès est invalide, échouer et demander à l'utilisateur de s'authentifier à nouveau

    avec jeton d'actualisation

    • envoyer une demande d'API avec un jeton d'accès
    • Si le jeton d'accès n'est pas valide, essayez de le mettre à jour en utilisant le jeton d'actualisation.
    • si la demande d'actualisation est acceptée, mettez à jour le jeton d'accès et renvoyez la demande d'API initiale
    • Si la requête d'actualisation échoue, demandez à l'utilisateur de s'authentifier à nouveau.

J'espère que cette réponse a du sens et aide quelqu'un à prendre une décision plus réfléchie. Je tiens également à souligner que certains fournisseurs OAuth2 bien connus, tels que github et foursquare, adoptent le protocole sans rafraîchir les jetons et semblent en être satisfaits.

519
Roman Imankulov

En dépit de toutes les bonnes réponses ci-dessus, en tant qu'étudiant en maîtrise de la sécurité et programmeur qui travaillait auparavant pour eBay lorsque je me suis penché sur la protection des acheteurs et la fraude, je peux dire que le jeton d'accès est séparé et que le jeton d'actualisation a son meilleur équilibre = entre l'utilisateur harcelant de fréquent la saisie du nom d'utilisateur/mot de passe et le maintien du pouvoir de révoquer l'accès aux abus potentiels de votre service.

Pensez à un scénario comme celui-ci. Vous émettez un utilisateur d'un jeton d'accès de 3600 secondes et l'actualisation d'un jeton beaucoup plus longtemps qu'un jour.

  1. L'utilisateur est un bon utilisateur, il est chez lui et met en marche/descend votre site internet pour magasiner et chercher sur son iPhone. Son adresse IP ne change pas et a une charge très faible sur votre serveur. Comme 3-5 demandes de page chaque minute. Lorsque ses 3600 secondes sur le jeton d'accès sont terminées, il en a besoin d'un nouveau avec le jeton d'actualisation. Du côté du serveur, nous vérifions l’historique de ses activités et son adresse IP, nous pensons qu’il est humain et qu’il se comporte bien. Nous lui accordons un nouveau jeton d'accès pour continuer à utiliser notre service. L'utilisateur n'aura pas besoin de saisir à nouveau le nom d'utilisateur/mot de passe jusqu'à ce qu'il ait atteint la durée de vie d'un jeton d'actualisation lui-même.

  2. L'utilisateur est un utilisateur négligent. Il vit à New York, États-Unis. Son programme de virus a été arrêté. Il a été piraté par un pirate informatique à Pologne. Lorsque le pirate informatique obtient le jeton d'accès et le jeton d'actualisation, il tente d'emprunter l'identité de l'utilisateur et utilise notre service. Mais après l'expiration du jeton d'accès à court terme, lorsque le pirate tente de rafraîchir le jeton d'accès, nous, sur le serveur, avons remarqué un changement radical d'adresse IP dans l'historique du comportement des utilisateurs (hé, ce gars se connecte aux États-Unis et rafraîchit maintenant l'accès en Pologne après seulement 3600 ???). Nous mettons fin au processus d'actualisation, invalidons le jeton d'actualisation lui-même et nous invitons à saisir à nouveau le nom d'utilisateur/mot de passe.

  3. L'utilisateur est un utilisateur malveillant. Il a l'intention d'abuser de notre service en appelant 1000 fois notre API chaque minute à l'aide d'un robot. Il peut très bien le faire jusqu'à 3600 secondes plus tard, lorsqu'il tente de rafraîchir le jeton d'accès, nous remarquons son comportement et pensons qu'il n'est peut-être pas un humain. Nous rejetons et mettons fin au processus d'actualisation et lui demandons de saisir à nouveau le nom d'utilisateur/mot de passe. Cela pourrait potentiellement interrompre le flux automatique de son robot. Au moins le met mal à l'aise.

Vous pouvez constater que le jeton d'actualisation a parfaitement fonctionné lorsque nous essayons d'équilibrer notre travail, notre expérience utilisateur et le risque potentiel d'un jeton volé. Votre chien de garde côté serveur peut vérifier davantage que le changement d'adresse IP, la fréquence des appels d'API pour déterminer si l'utilisateur doit être un bon utilisateur ou non.

Un autre mot est que vous pouvez également essayer de limiter le contrôle des dommages causés par un jeton volé/un abus de service en mettant en œuvre à chaque appel api le chien de garde IP de base ou toute autre mesure. Mais cela coûte cher car vous devez lire et écrire des informations sur l’utilisateur et ralentir la réponse de votre serveur.

163
laalaguer

Aucune de ces réponses n'aboutit à la raison principale pour laquelle les jetons d'actualisation existent. Évidemment, vous pouvez toujours obtenir une nouvelle paire jeton d'accès/rafraîchissement-jeton en envoyant les informations d'identification de votre client au serveur d'authentification - c'est ainsi que vous les obtenez en premier lieu.

Le jeton d'actualisation a donc pour seul objectif de limiter l'utilisation des informations d'identification du client envoyées par le réseau filaire au service d'authentification. Plus le ttl du jeton d'accès est court, plus les informations d'identification du client devront souvent être utilisées pour obtenir un nouveau jeton d'accès. Par conséquent, plus les attaquants ont la possibilité de compromettre les informations d'identification du client (même si cela peut s'avérer extrêmement difficile si cryptage asymétrique est utilisé pour les envoyer). Ainsi, si vous disposez d'un jeton d'actualisation à usage unique, vous pouvez réduire arbitrairement le ttl des jetons d'accès sans compromettre les informations d'identification du client.

67
B T

Pour dissiper toute confusion, vous devez comprendre les rôles du secret du client et du mot de passe utilisateur , qui sont très différents.

Le client est une application/site web/programme/..., adossé à un serveur, qui veut s'authentifier a utilisateur en utilisant un service d'authentification tiers. Le secret du client est une chaîne (aléatoire) connue à la fois de ce client et du serveur d'authentification. En utilisant ce secret, le client peut s'identifier avec le serveur d'authentification en recevant l'autorisation de demander des jetons d'accès.

Pour obtenir le jeton d'accès initial et le jeton d'actualisation, il faut:

  • L'ID utilisateur
  • Le mot de passe utilisateur
  • L'identifiant du client
  • Le secret du client

Pour obtenir un jeton d'accès actualisé, le client utilise les informations suivantes:

  • L'identifiant du client
  • Le secret du client
  • Le jeton d'actualisation

Cela montre clairement la différence: lors de l'actualisation, le client reçoit l'autorisation d'actualiser les jetons d'accès à l'aide de son secret client et peut ainsi ré-authentifier l'utilisateur à l'aide du jeton d'actualisation de l'ID utilisateur + mot de passe. Cela évite efficacement à l'utilisateur de devoir ressaisir son mot de passe.

Cela montre également que la perte d'un jeton d'actualisation n'est pas un problème car l'ID client et le secret ne sont pas connus. Cela montre également que garder l'ID client et le secret client est vital .

45
Adversus

Cette réponse provient de Justin Richer via la liste d'e-mails du corps standard OAuth 2. Ceci est posté avec sa permission.


La durée de vie d'un jeton d'actualisation dépend du serveur d'autorisation (AS) - ils peuvent expirer, être révoqués, etc. La différence entre un jeton d'actualisation et un jeton d'accès réside dans l'audience: le jeton d'actualisation ne renvoie qu'au serveur d'autorisation, le jeton d'accès va au serveur de ressources (RS).

De plus, le simple fait d’obtenir un jeton d’accès ne signifie pas que l’utilisateur est connecté. En fait, il se peut même que l’utilisateur n’y soit plus, ce qui est en fait le cas d’utilisation du jeton d’actualisation. L'actualisation du jeton d'accès vous donnera accès à une API pour le compte de l'utilisateur. Elle ne vous dira pas si l'utilisateur est présent.

OpenID Connect ne vous fournit pas seulement les informations d’utilisateur à partir d’un jeton d’accès, il vous donne également un jeton d’identification. Il s’agit d’une donnée distincte qui est dirigée vers le client lui-même, et non pas l’AS ou le RS. Dans OIDC, vous ne devriez envisager une personne réellement "connectée" par le protocole que si vous pouvez obtenir un nouveau jeton d'identification. Rafraîchissant, cela ne sera probablement pas suffisant.

Pour plus d'informations, veuillez lire http://oauth.net/articles/authentication/

35
Manicode

Les clients peuvent être compromis de plusieurs façons. Par exemple, un téléphone cellulaire peut être cloné. L'expiration d'un jeton d'accès signifie que le client est obligé de s'authentifier de nouveau sur le serveur d'autorisation. Lors de la réauthentification, le serveur d'autorisation peut vérifier d'autres caractéristiques (IOW effectue la gestion des accès adaptatifs).

Les jetons d'actualisation autorisent uniquement la réauthentification du client. Dans ce cas, cette opération force un dialogue avec l'utilisateur que beaucoup ont indiqué préférer ne pas faire.

Les jetons de rafraîchissement s’intègrent essentiellement au même endroit où des sites Web normaux peuvent choisir de ré-authentifier périodiquement les utilisateurs au bout d’une heure environ (par exemple, un site bancaire). Il n'est pas très utilisé à l'heure actuelle car la plupart des sites Web sociaux ne ré-authentifient pas les utilisateurs, alors pourquoi voudraient-ils réauthentifier un client?

18
Phil

Pour simplifier davantage la réponse de B T: Utilisez des jetons d'actualisation lorsque vous ne souhaitez généralement pas que l'utilisateur soit obligé de saisir à nouveau les informations d'identification, mais que vous souhaitiez tout de même pouvoir révoquer les autorisations (en révoquant le jeton d'actualisation).

Vous ne pouvez pas révoquer un jeton d'accès, mais seulement un jeton d'actualisation.

11
bitcoder

Pourquoi ne pas simplement laisser access_token durer aussi longtemps que refresh_token et ne pas avoir un refresh_token?

Outre les bonnes réponses fournies par d'autres personnes, il existe une autre raison pour laquelle utiliser des jetons d'actualisation et son rapport avec les revendications.

Chaque jeton contient des revendications pouvant inclure n'importe quoi, à partir du nom de l'utilisateur, de ses rôles ou du fournisseur qui a créé la revendication. Lorsqu'un jeton est actualisé, ces revendications sont mises à jour.

Si nous actualisons les jetons plus souvent, nous mettons évidemment plus de pression sur nos services d'identité, mais nous obtenons des revendications plus précises et à jour.

10
heymega

Supposons que vous laissez le code access_token durer très longtemps et que vous n’ayez pas de variable refresh_token. Ainsi, en un jour, un pirate informatique obtiendra ce code_accès et pourra accéder à toutes les ressources protégées!

Mais si vous avez refresh_token, la durée de vie de access_token est courte. Il est donc difficile au pirate informatique de pirater votre access_token, car il ne sera plus valide après une courte période. Access_token ne peut être récupéré qu'en utilisant non seulement refresh_token, mais également par client_id et client_secret, ce que n'a pas piraté.

5
Tạ Anh Tú

Pendant que le jeton d'actualisation est conservé par le serveur d'autorisation. Les jetons d'accès sont autonomes, de sorte que le serveur de ressources peut le vérifier sans le stocker, ce qui évite l'effort de récupération en cas de validation. Un autre point qui manque dans la discussion est celui de rfc6749 # page-55

"Par exemple, le serveur d'autorisation peut utiliser une rotation de jeton d'actualisation dans laquelle un nouveau jeton d'actualisation est émis avec chaque réponse d'actualisation de jeton d'accès. Le jeton d'actualisation précédent est invalidé mais conservé par le serveur d'autorisation. Si un jeton d'actualisation est compromis et utilisé ultérieurement par L'attaquant et le client légitime, l'un d'eux présentera un jeton d'actualisation invalidé, qui informera le serveur d'autorisation de la violation. "

Je pense que l'intérêt d'utiliser le jeton d'actualisation est que même si l'attaquant parvient à obtenir une combinaison de jeton d'actualisation, d'identifiant client et de secret. Les appels suivants destinés à obtenir un nouveau jeton d'accès de la part de l'attaquant peuvent être suivis au cas où chaque demande d'actualisation donnerait un nouveau jeton d'accès et un jeton d'actualisation.

2
Kraming

Cette réponse a été préparée avec l'aide de deux développeurs seniors (John Brayton et David Jennes).

La raison principale d'utiliser un jeton d'actualisation est de réduire la surface d'attaque.

Supposons qu’il n’existe pas de clé d’actualisation et examinons cet exemple:

Un bâtiment a 80 portes. Toutes les portes sont ouvertes avec la même clé. La clé change toutes les 30 minutes.

Si je suis le pirate informatique et que je récupère votre clé, à la fin des 30 minutes, je le ferai parvenir par courrier au fabricant de clés et obtiendrai une nouvelle clé. Je pourrai ouvrir en permanence toutes les portes, quelle que soit la clé changée.

Question: Pendant les 30 minutes, combien d’opportunités de piratage ai-je eu contre la clé? J'ai eu 80 occasions de piratage, chaque fois que vous avez utilisé la clé (pensez à cela comme à une requête réseau et à la transmission du jeton d'accès pour vous identifier). La surface d’attaque est donc 80X.

Reprenons maintenant le même exemple, mais cette fois-ci, supposons qu’il existe une clé de rafraîchissement.

Un bâtiment a 80 portes. Toutes les portes sont ouvertes avec la même clé. La clé change toutes les 30 minutes. Si je suis le pirate informatique et que je récupère votre clé, je peux l’utiliser pendant 30 minutes, mais au bout de ces 30 minutes, l’envoyer au fabricant de clés n’a aucune valeur. Si je le fais, le fabricant de clés dira simplement que cette clé est expirée. Pour pouvoir prolonger mon piratage, je devrais pirater le courrier au fabricant de clés. Le service de messagerie a une clé distincte (considérez cela comme un jeton d'actualisation).

Question: Pendant les 30 minutes, combien d’opportunités de piratage ai-je eu contre le courrier? 80? Non, je n'ai eu qu'une seule opportunité de piratage informatique. Pendant le temps, le courrier communique avec le fabricant de clés. C’est donc une surface d’attaque 1X. J'ai eu 80 occasions de piratage contre la clé, mais elles ne sont plus bonnes après 30 minutes.


Un serveur vérifierait un jeton d'accès en fonction des informations d'identification et de la signature (généralement) d'un JWT.

Une fuite de jeton d'accès est mauvaise, mais une fois expirée, elle n'est plus utile pour un attaquant. Une fuite de jeton d'actualisation est bien pire, mais probablement moins probable. (Je pense qu’il est possible de se demander si la probabilité d’une fuite de jeton de rafraîchissement est bien inférieure à celle d’un jeton de fuite d’accès, mais c’est l’idée.)

Le point est que le jeton d'accès est ajouté à chaque requête que vous faites, alors qu'un jeton d'actualisation n'est utilisé que pendant le flux d'actualisation. Ainsi, moins de chances qu'un MITM voie le jeton

La fréquence aide un attaquant. Heartbleed - comme les failles de sécurité potentielles de SSL, les failles de sécurité potentielles du client et les failles de sécurité potentielles du serveur, permettent toutes les fuites.

De plus, si le serveur d'autorisation est distinct du serveur d'applications qui traite d'autres demandes client, ce dernier ne verra jamais les jetons d'actualisation. Il ne verra que les jetons d'accès qui ne vivront plus très longtemps.

La compartimentation est bonne pour la sécurité.


Quel est le jeton d'actualisation ne concerne PAS?

La possibilité de mettre à jour/révoquer le niveau d'accès à l'aide de jetons d'actualisation est un sous-produit du choix d'utiliser des jetons d'actualisation. Sinon, un jeton d'accès autonome pourrait être révoqué ou son niveau d'accès modifié lorsqu'il expirera et que les utilisateurs recevront un nouveau jeton ".

1
Honey

Tout d'abord, le client s'authentifie auprès du serveur d'autorisations en lui accordant l'autorisation.

Ensuite, le client demande au serveur de ressources la ressource protégée en donnant le jeton d'accès.

Le serveur de ressources valide le jeton d'accès et fournit la ressource protégée.

Le client envoie la demande de ressource protégée au serveur de ressources en accordant le jeton d'accès. Le serveur de ressources le valide et sert la demande, le cas échéant. Cette étape se répète jusqu'à l'expiration du jeton d'accès.

Si le jeton d'accès expire, le client s'authentifie auprès du serveur d'autorisation et demande un nouveau jeton d'accès en fournissant un jeton d'actualisation. Si le jeton d'accès n'est pas valide, le serveur de ressources renvoie la réponse d'erreur de jeton invalide au client.

Le client s'authentifie auprès du serveur d'autorisation en accordant le jeton d'actualisation.

Le serveur d'autorisation valide ensuite le jeton d'actualisation en authentifiant le client et émet un nouveau jeton d'accès, s'il est valide.

0
user8288060

Considérons un système dans lequel chaque utilisateur est lié à un ou plusieurs rôles et chaque rôle est lié à un ou plusieurs privilèges d'accès. Ces informations peuvent être mises en cache pour améliorer les performances de l'API. Mais ensuite, il peut y avoir des changements dans les configurations des utilisateurs et des rôles (par exemple, un nouvel accès peut être accordé ou un accès actuel peut être révoqué) et ceux-ci doivent être reflétés dans le cache.

Nous pouvons utiliser l'accès et actualiser les jetons à cette fin. Lorsqu'une API est appelée avec un jeton d'accès, le serveur de ressources vérifie dans le cache les droits d'accès. S'il y a de nouvelles subventions d'accès, cela ne se reflète pas immédiatement. Une fois que le jeton d'accès a expiré (par exemple, au bout de 30 minutes) et que le client utilise le jeton d'actualisation pour générer un nouveau jeton d'accès, le cache peut être mis à jour avec les informations de droit d'accès d'utilisateur mises à jour de la base de données.

En d'autres termes, nous pouvons déplacer les opérations coûteuses de chaque appel d'API à l'aide de jetons d'accès vers l'événement de génération de jeton d'accès à l'aide de l'actualisation du jeton.

0
Saptarshi Basu