web-dev-qa-db-fra.com

Comment garder les informations d'identification du client confidentielles, tout en utilisant le type d'octroi des informations d'identification du mot de passe du propriétaire des ressources d'OAuth2

Nous construisons un service de repos et nous voulons utiliser OAauth 2 pour l'autorisation. Le version actuelle (v2-16 du 19 mai) décrit quatre types de subventions . Ce sont des mécanismes ou des flux pour obtenir une autorisation (un jeton d'accès).

  1. Code d'autorisation
  2. Subvention implicite
  3. Informations d'identification du propriétaire de la ressource
  4. Informations d'identification du client

Il semble que nous devons les soutenir tous les quatre, car ils ont des objectifs différents. Les deux premiers (et peut-être le dernier) peuvent être utilisés à partir d'applications tierces qui ont besoin d'accéder à l'API. Le code d'autorisation est le moyen standard d'autoriser une application Web qui a la chance de résider sur un serveur sécurisé, tandis que le flux d'octroi implicite serait le choix pour une application cliente qui ne peut pas tout à fait garder ses informations d'identification confidentielles (par exemple, mobile/ordinateur de bureau). application, client JavaScript, etc.).
Nous voulons utiliser le troisième mécanisme nous-mêmes pour offrir une meilleure expérience utilisateur sur les appareils mobiles - au lieu de conduire l'utilisateur à une boîte de dialogue de connexion dans un navigateur Web et ainsi de suite, l'utilisateur saisira simplement son nom d'utilisateur et mot de passe directement dans l'application et connectez-vous. Nous souhaitons également utiliser le type d'autorisation Client Credentials pour obtenir un jeton d'accès qui peut être utilisé pour afficher des données publiques, non associé à un utilisateur. Dans ce cas, il ne s'agit pas tant d'une autorisation, mais plutôt de quelque chose de similaire à une clé API que nous utilisons pour donner accès uniquement aux applications qui se sont enregistrées auprès de nous, nous donnant la possibilité de révoquer l'accès si nécessaire.

Mes questions sont donc:

  1. Pensez-vous que j'ai bien compris l'objectif des différents types de subventions?
  2. Comment pouvez-vous garder les informations d'identification de votre client confidentielles? Dans les troisième et quatrième cas, nous devons avoir l'ID client et le secret client quelque part sur le client, ce qui ne semble pas être une bonne idée.
  3. Même si vous utilisez le type d'autorisation implicite et que vous n'exposez pas le secret de votre client, qu'est-ce qui empêche une autre application d'usurper l'identité de votre application en utilisant le même mécanisme d'autorisation et votre identifiant client?

Pour résumer, nous souhaitons pouvoir utiliser les informations d'identification du client et les informations d'identification du propriétaire de la ressource à partir d'une application client. Ces deux flux nécessitent que vous stockiez le secret du client d'une manière ou d'une autre, mais le client est une application mobile ou JavaScript, donc ceux-ci pourraient facilement être volés.

74
Georgi Stoyanov

Je suis confronté à des problèmes similaires et je suis également relativement nouveau à OAuth. J'ai implémenté les "informations d'identification du mot de passe du propriétaire des ressources" dans notre API pour que notre application mobile officielle puisse les utiliser - les flux Web semblent être tellement horribles à utiliser sur une plate-forme mobile, et une fois que l'utilisateur a installé une application et fait confiance que c'est notre application officielle, ils devraient se sentir à l'aise de taper le nom d'utilisateur/mot de passe directement dans l'application.

Le problème est, comme vous le faites remarquer, qu'il n'y a aucun moyen pour mon serveur API de vérifier en toute sécurité l'identifiant client de l'application. Si j'inclus un client_secret dans le code/package de l'application, il est exposé à toute personne qui installe l'application, donc exiger un client_secret ne rendrait pas le processus plus sécurisé. Donc, fondamentalement, toute autre application peut emprunter l'identité de mon application en copiant le client_id.

Juste pour orienter les réponses sur chacun de vos points:

  1. Je continue de relire différentes versions de la spécification pour voir si quelque chose a changé, et je me concentre principalement sur la section Informations d'identification du mot de passe du propriétaire de la ressource, mais je pense que vous avez raison à ce sujet. Informations d'identification du client (4) Je pense que pourrait également être utilisé par un service interne ou tiers qui pourrait avoir besoin d'accéder à plus que des informations "publiques", comme peut-être que vous avez des analyses ou quelque chose qui doit obtenir des informations auprès de tous les utilisateurs.

  2. Je ne pense pas que vous puissiez garder quoi que ce soit de confidentiel sur le client.

  3. Rien n'empêche quelqu'un d'autre d'utiliser votre identifiant client. C'est aussi mon problème. Une fois que votre code quitte le serveur et est installé en tant qu'application ou s'exécute en tant que Javascript dans un navigateur, vous ne pouvez pas supposer que quelque chose est secret.

Pour notre site Web, nous avons rencontré un problème similaire à ce que vous décrivez avec le flux d'informations d'identification du client. J'ai fini par déplacer l'authentification côté serveur. L'utilisateur peut s'authentifier à l'aide de notre application Web, mais le jeton OAuth de notre API est stocké côté serveur et associé à la session Web de l'utilisateur. Toutes les demandes d'API effectuées par le code Javascript sont en fait AJAX appelle le serveur Web. Le navigateur n'est donc pas directement authentifié avec l'API, mais dispose plutôt d'une session Web authentifiée.

Il semble que votre cas d'utilisation pour les informations d'identification du client soit différent, dans la mesure où vous parlez d'applications tierces et ne diffusez des données publiques que par cette méthode. Je pense que vos préoccupations sont valables (n'importe qui peut voler et utiliser la clé d'API de quelqu'un d'autre), mais si vous n'avez besoin que d'une inscription gratuite pour obtenir une clé d'API, je ne vois pas pourquoi quelqu'un voudrait vraiment en voler une.

Vous pouvez surveiller/analyser l'utilisation de chaque clé API pour essayer de détecter les abus, à quel point vous pouvez invalider une clé API et en donner une nouvelle à l'utilisateur légitime. C'est peut-être la meilleure option, mais ce n'est en aucun cas sécurisé.

Vous pouvez également utiliser un schéma de type Refresh Token si vous souhaitez le verrouiller un peu plus, même si je ne sais pas combien vous gagneriez vraiment. Si vous expiriez les jetons api exposés à Javascript une fois par jour et exigiez que le tiers fasse une sorte de rafraîchissement côté serveur en utilisant un jeton de rafraîchissement (secret), alors les jetons api volés ne seraient jamais bons pendant plus d'une journée. Cela pourrait encourager les voleurs de jetons potentiels à simplement s'inscrire à la place. Mais une sorte de douleur pour tout le monde, donc je ne sais pas si cela en vaut la peine.

55
heavi5ide