OAuth2 ROPC vs Basic Auth pour les API REST publiques?

21

Le cas d'utilisation spécifique qui m'intéresse ici est l'authentification des clients REST par rapport aux points de terminaison de serveur accessibles au public (comme une API REST publique).

La solution la plus simple ici est Basic Auth . Mais j'entends souvent OAuth2 présenté comme une solution d'authentification supérieure dans presque toutes les circonstances.

Le fait est que le seul type d'octroi OAuth2 qui est possible pour un client REST s'authentifiant sur un serveur REST est les informations d'identification du mot de passe du propriétaire des ressources (ROPC) , car les octrois de code et les octrois implicites nécessitent une interface utilisateur / page Web (hébergée par le serveur Auth) pour le l'utilisateur pour se connecter et autoriser manuellement l'application cliente.

Le fonctionnement du ROPC consiste à envoyer le nom d'utilisateur / mot de passe du propriétaire de la ressource et l'ID client en tant que paramètres de chaîne de requête ?!? C'est encore moins sécurisé (IMHO) que Basic Auth, qui au moins base-64 code les informations d'identification et les envoie à l'intérieur d'un en-tête qui peut être chiffré par TLS!

Je demande donc: dans le contexte des API REST publiques, OAuth2 ROPC est-il vraiment meilleur que Basic Auth? Quoi de plus sûr que le ROPC OAuth2?


Mise à jour

Je viens de lire cet excellent article qui explique la sécurité REST non basée sur OAuth2 d'Amazon pour AWS. Il s'agit essentiellement d'une solution basée sur une clé privée où les hachages de chaque demande REST sont générés et envoyés en tant que side-cars à côté de la demande normale (non chiffrée). Seuls le client et le serveur connaissent la clé privée, donc lorsque le serveur reçoit la demande (contenant à nouveau la demande normale + la demande hachée), le serveur recherche la clé privée du client, applique le même hachage à la demande normale, et compare ensuite les deux hachages.

Cela semble beaucoup plus compliqué, complexe et sécurisé que le ROPC d'OAuth2! Sauf si je manque quelque chose de majeur ici, OAuth2 ROPC est juste en train d'envoyer client_id, usernameet en passwordtant que paramètres de chaîne de requête ... totalement et totalement non sécurisé! Cette solution basée sur HMAC / hachée semble être beaucoup plus impressionnante et sécurisée.

Le fait est que même l'auteur de cet article poursuit:

Vous [réaliserez] aussi lentement et accepterez qu'à un moment donné, vous devrez implémenter OAuth ...

Ba-ba-b quoi?!?! Si OAuth2 est moins sécurisé que cette solution intelligente basée sur HMAC / hash, pourquoi l'auteur de cet article pense-t-il qu'OAuth doit être adopté à un moment donné. Je suis tellement confus.

smeeb
la source
De quel type de client parlez-vous? Je suppose que la plupart des clients auront une interface utilisateur. Dans ce cas, vous pouvez charger la page de connexion OAuth dans une vue Web (ordinateur de bureau, mobile) ou la rediriger directement (Web). Je ne vois pas pourquoi vous devez éviter l'interface utilisateur.
décyclone du
@decyclone veuillez lire la toute première phrase de la question! Je prends des clients REST (HTTP sans tête) s'authentifiant contre les services REST.
smeeb
La question que je pose est de savoir si ce client a une interface utilisateur? Même si ce n'était pas le cas, j'ai vu des applications sans interface utilisateur ouvrir une boîte de dialogue au moins pour l'authentification.
décyclone du
@decyclone no un client REST pur n'a aucune interface utilisateur, bien que les interfaces utilisateur utilisent généralement un client REST pur pour se connecter à un service REST. Un cas d'utilisation est un outil de ligne de commande qui utilise un client REST pour envoyer des commandes utilisateur (entrées sur le shell) au service REST. Popping une interface utilisateur à partir d'un shell n'est tout simplement pas une solution acceptable ici.
smeeb
1
Mais, je dois noter qu'il existe de nombreux autres cas d'utilisation en dehors d'une ligne de commande / shell. Un autre cas d'utilisation est un client Java / Ruby / Python pur REST / HTTP qui n'a pas d'interface utilisateur et peut être exécuté sur un serveur principal sans interface utilisateur. Le serveur principal doit communiquer avec un autre serveur principal via REST. Ici, non seulement il serait maladroit et hacky de faire apparaître une interface utilisateur lorsque le serveur principal # 1 doit parler au serveur principal # 2, le vrai problème est qu'il n'y a pas de navigateur / client d'interface utilisateur pour afficher la page de connexion, et il n'y a pas d'humain être là pour se connecter !!!
smeeb

Réponses:

24

La réponse à votre question peut être au niveau du code, du protocole ou de l'architecture. Je vais essayer de résumer ici la plupart des problèmes au niveau du protocole, car cela est généralement critique dans l'analyse des avantages et des inconvénients. Gardez à l'esprit que OAuth2 est bien plus que les informations d'identification du mot de passe du propriétaire de la ressource qui, selon la spécification, existent pour des "raisons d'héritage ou de migration", sont considérées comme "à risque plus élevé que les autres types de subvention" et la spécification indique explicitement que les clients et les serveurs d'autorisation "DEVRAIT minimiser l'utilisation de ce type de subvention et utiliser d'autres types de subvention dans la mesure du possible".

Il existe encore de nombreux avantages à utiliser ROPC par rapport à l'authentification de base, mais avant d'entrer dans le détail, comprenons la différence de protocole de base entre OAuth2 et l'authentification de base. S'il vous plaît, restez avec moi pendant que j'explique cela et je reviendrai au ROPC plus tard.

Flux d'authentification des utilisateurs

Il existe quatre rôles définis dans la spécification OAuth2. Avec des exemples, ce sont:

  1. Propriétaire de la ressource: l'utilisateur qui a accès à une ressource, par exemple dans votre cas, différents utilisateurs peuvent avoir un niveau d'accès différent à l'API REST;
  2. Le client: généralement l'application que l'utilisateur utilise et a besoin d'accéder à la ressource pour fournir des services à l'utilisateur;
  3. Serveur de ressources: l'API REST dans votre cas; et
  4. Serveur d'autorisation: le serveur auquel les informations d'identification de l'utilisateur sont présentées et qui authentifiera l'utilisateur.

Lorsqu'une application cliente s'exécute, elle se voit accorder l'accès aux ressources en fonction de l'utilisateur. Si un utilisateur dispose de privilèges d'administrateur, les ressources et opérations disponibles pour l'utilisateur dans l'API REST peuvent être bien plus qu'un utilisateur sans privilèges d'administrateur.

OAuth2 offre également la possibilité d'utiliser un seul serveur d'autorisation avec plusieurs clients et pour plusieurs ressources. Par exemple, un serveur de ressources peut accepter l'authentification de l'utilisateur avec Facebook (qui peut agir comme serveur d'autorisation dans un tel cas). Ainsi, lorsque l'utilisateur exécute une application (c'est-à-dire le client), il envoie l'utilisateur à Facebook. L'utilisateur saisit ses informations d'identification dans Facebook et le client récupère un "jeton" qu'il peut présenter au serveur de ressources. Le serveur de ressources examine le jeton et l'accepte après avoir vérifié que Facebook l'a effectivement émis et autorise l'utilisateur à accéder à la ressource. Dans ce cas, le client ne voit jamais les informations d'identification de l'utilisateur (c'est-à-dire ses informations d'identification Facebook).

Mais disons que vous gérez les identités de vos utilisateurs (et avez un serveur d'autorisation) au lieu de Facebook, qui accorde déjà des jetons à votre client. Supposons maintenant que vous ayez également un partenaire et que vous souhaitiez autoriser son application (c'est-à-dire son client) à accéder à votre API REST. Avec l'authentification de base (ou même ROPC), l'utilisateur fournira des informations d'identification à ce client qui les enverra au serveur d'autorisation. Le serveur d'autorisation fournira alors un jeton qui peut être utilisé par le client pour accéder aux ressources. Malheureusement, cela signifie que les informations d'identification de l'utilisateur sont désormais visibles pour ce client également. Cependant, vous ne voudriez pas que l'application d'un partenaire (qui pourrait être externe à votre organisation) connaisse même le mot de passe d'un utilisateur. C'est un problème de sécurité maintenant. Pour atteindre cet objectif,

Ainsi, avec OAuth2, l'idéal serait de ne pas utiliser ROPC dans de tels cas plutôt d'utiliser un autre, comme le flux de code d'autorisation. Cela protège toute application de connaître les informations d'identification de l'utilisateur qui ne sont présentées qu'au serveur d'autorisation. Ainsi, les informations d'identification d'un utilisateur ne sont pas divulguées. Les mêmes problèmes s'appliquent à l'authentification de base, mais dans la section suivante, j'expliquerai comment ROPC est encore meilleur car les informations d'identification de l'utilisateur n'ont toujours pas besoin d'être stockées par le client dans ROPC pour un accès persistant par les clients.

Notez que lorsque l'utilisateur accède au serveur d'autorisation, le serveur d'autorisation peut également demander à l'utilisateur de confirmer qu'il souhaite autoriser le client à accéder aux ressources en son nom ou non. C'est pourquoi il est appelé serveur d'autorisation car le processus d'autorisation d'un client pour accéder aux ressources est impliqué dans le processus. Si l'utilisateur n'autorise pas le client, il n'aura pas accès aux ressources. De même, si l'utilisateur lui-même n'a pas accès aux ressources, le serveur d'autorisation peut toujours refuser l'accès et ne pas émettre de jeton.

Dans l'authentification de base, même le serveur d'autorisation et le serveur de ressources sont combinés en une seule entité. Ainsi, le serveur de ressources veut autoriser l'utilisateur, demande donc les informations d'identification du client. Le client fournit les informations d'identification utilisées par le serveur de ressources pour authentifier l'utilisateur. Cela signifie que plusieurs serveurs de ressources exigeront essentiellement des informations d'identification de l'utilisateur.

Émission de jetons

Les clients obtiennent des jetons du serveur d'autorisation, les conservent et les utilisent pour accéder aux ressources (plus de détails sur les jetons eux-mêmes ci-dessous). Les clients ne connaissent jamais le mot de passe de l'utilisateur (dans des flux autres que ROPC) et n'ont pas besoin de le stocker. Dans ROPC, même si les clients connaissent le mot de passe de l'utilisateur, ils n'ont toujours pas besoin de le stocker car ils utilisent ces jetons pour accéder aux ressources. En revanche, dans l'authentification de base, si un client ne souhaite pas que l'utilisateur fournisse des informations d'identification à chaque session, le client doit stocker le mot de passe de l'utilisateur afin de pouvoir le fournir la prochaine fois. C'est un inconvénient majeur de l'utilisation de l'authentification de base, sauf si le client n'est qu'une application Web, auquel cas les cookies peuvent répondre à certaines de ces préoccupations. Avec les applications natives, ce n'est généralement pas une option.

Il y a un autre aspect d'OAuth2 qui est impliqué dans la façon dont les jetons sont émis et fonctionnent. Lorsqu'un utilisateur fournit des informations d'identification au serveur d'autorisation (même dans ROPC), le serveur d'autorisation peut attribuer un ou plusieurs des deux types de jetons: 1) jeton d'accès et 2) jeton d'actualisation.

Les jetons d'accès sont envoyés au serveur de ressources qui accordera l'accès aux ressources après leur validation, et ils ont généralement une courte durée de vie, par exemple 1 heure. Les jetons d'actualisation sont envoyés au serveur d'autorisation par le client pour obtenir un autre jeton d'accès à son expiration, et ont généralement une grande durée de vie (par exemple quelques jours à plusieurs mois voire plusieurs années).

Lorsque le client fournit le jeton d'accès au serveur de ressources, il regarde le jeton et après validation, regarde à l'intérieur du jeton pour déterminer s'il autorise l'accès ou non. Tant que le jeton d'accès est valide, le client peut continuer à l'utiliser. Supposons que l'utilisateur ferme l'application et la démarre le lendemain, et le jeton d'accès a expiré. Le client va maintenant appeler le serveur d'autorisation et présenter le jeton d'actualisation en supposant qu'il n'est pas expiré. Le serveur d'autorisation, puisqu'il a déjà émis le jeton, le vérifie et peut déterminer que l'utilisateur n'a pas besoin de fournir à nouveau les informations d'identification et donne ainsi un autre jeton d'accès au client. Le client a à nouveau accès au serveur de ressources. C'est ainsi que les applications clientes pour Facebook et Twitter demandent généralement des informations d'identification une fois, puis ne demandent pas à l'utilisateur de fournir à nouveau les informations d'identification. Ces applications n'ont jamais besoin de connaître les informations d'identification des utilisateurs et peuvent néanmoins accéder aux ressources chaque fois que l'utilisateur démarre l'application.

L'utilisateur peut désormais accéder au serveur d'autorisation (par exemple dans son profil d'utilisateur Facebook), changer de mot de passe sans impact sur les applications clientes. Ils continueront tous à fonctionner correctement. Si l'utilisateur perd un appareil sur lequel il avait déjà une application avec des jetons d'actualisation, il peut demander au serveur d'autorisation (par exemple Facebook) de "se déconnecter" des applications que le serveur d'autorisation (par exemple Facebook) accomplira en n'honorant aucune actualiser les jetons et forcer l'utilisateur à fournir à nouveau des informations d'identification lorsqu'il essaie d'accéder aux ressources via ces applications.

JWT est simplement le format de jeton généralement utilisé avec OAuth2 et OpenID Connect. Les méthodes de signature et de validation du jeton sont également standardisées avec des bibliothèques disponibles pour ceux-ci au lieu que chaque serveur de ressources implémente une autre solution. Ainsi, l'avantage réside dans la réutilisabilité du code qui a été vérifié et continue d'être pris en charge.

Implications pour la sécurité

L'authentification de base sera plus faible lorsque l'un des scénarios ci-dessus apparaît dans l'image. Il existe également un modèle de menace étendu pour OAuth2 disponible pour les développeurs qui peuvent utiliser les suggestions qu'il contient pour éviter les vulnérabilités courantes dans leurs implémentations. Si vous passez par le modèle de menace, vous verrez que de nombreuses vulnérabilités liées à l'implémentation (telles que le redirecteur ouvert et CSRF) y sont également couvertes. Je ne suis pas passé par la comparaison de ceux contre l'authentification de base dans cette réponse.

Le dernier avantage majeur d'OAuth2 est que le protocole est standardisé et que plusieurs serveurs d'autorisation, clients et serveurs de ressources l'honorent. De nombreuses bibliothèques sont disponibles pour les développeurs, qui sont maintenues afin que des problèmes de sécurité soient trouvés dans les implémentations, les bibliothèques sont mises à jour tout en permettant l'interopérabilité.

Conclusion

Si vous écrivez une nouvelle application, IMO, le cas idéal serait d'éviter à la fois l'authentification de base et le ROPC en raison des problèmes inhérents à celles-ci. Cependant, chaque application a des besoins, des délais, des compétences de développeur, etc. différents, donc la décision est prise au cas par cas. Mais même si vous n'aviez pas plus besoin que l'authentification de base, en la choisissant, vous pourriez vous enfermer dans une architecture qui ne serait pas facile à étendre (par exemple si vous avez plusieurs serveurs à l'avenir, vous ne voudriez pas nécessairement avoir l'utilisateur fournit des informations d'identification à chacun d'eux plutôt qu'il suffit de fournir une fois au serveur d'autorisation, qui peut distribuer des jetons, etc.)

Notez que je n'ai pas répondu à votre commentaire sur la façon dont les informations d'identification sont envoyées par câble, car celles-ci peuvent être sécurisées à l'aide de TLS ou d'un protocole similaire, ou d'une preuve de possession, etc. être trompé par cela. Les différences mentionnées ci-dessus sont généralement au niveau architectural et c'est donc là que je me suis concentré car l'architecture est la plus difficile à changer une fois mise en œuvre.

Azure Active Directory B2C Basic , un service sur lequel je travaille et qui a récemment été publié en avant-première publique, permet à une application tierce d'utiliser AAD comme serveur d'autorisation avec interopérabilité avec les PDI sociaux (tels que Facebook, Google, etc.). Il permet également aux utilisateurs de créer leurs propres comptes au lieu d'utiliser des PDI sociaux et ceux-ci peuvent ensuite être utilisés à des fins d'authentification. Il y a quelques autres services comme ça (par exemple un autre que je connais est auth0) qui peut être utilisé par les développeurs pour externaliser complètement l'authentification et la gestion des utilisateurs pour leurs applications et ressources. Les mêmes caractéristiques de protocoles que j'ai mentionnées ci-dessus sont utilisées par les développeurs pour découpler le serveur d'autorisation (AAD), une ressource (par exemple leurs API REST), le client (par exemple leurs applications mobiles) et les utilisateurs. J'espère que cette explication aide un peu.

Omer Iqbal
la source
Merci pour un grand angle, mais je ne pense pas que ces avantages (a) letting the user agent hold just the token instead of the password, (b) allowing a password change without disrupting existing client apps, (c) allowing users log out other sessionssoient spécifiques aux flux d'authentification par jeton. Ni l'authentification de base ni l'authentification par jeton ne mentionnent les fonctions (b) et (c) dans leurs spécifications. L'implémentation de (b) et (c) semble possible pour tout type d'authentification. Cela impliquerait de garder une trace des mots de passe (de préférence leurs hachages). L'avantage (a) semble dépendre de la portée plus large du mot de passe.
eel ghEEz
Comment pourrions-nous utiliser OAuth si l'utilisateur (propriétaire de la ressource) n'a pas d'informations d'identification avec un serveur d'autorisation externe, mais qu'il a des informations d'identification dans l'application cliente? C'est-à-dire que nous avons le propriétaire de la ressource (utilisateur), le client (représentant l'utilisateur et contenant également les informations d'identification pour l'utilisateur) et le serveur de ressources. Comment un serveur de ressources peut-il authentifier et autoriser l'utilisateur?
Arun Avanathan
3

Je pense que vous êtes mal informé sur le chiffrement des variables GET dans une URL

Les seules personnes qui peuvent afficher les variables GET dans une demande sont l'ordinateur d'origine et le serveur de réception ( lien ).

Seule la recherche DNS basée sur le domaine auquel la demande HTTPS est envoyée n'est pas chiffrée. Tout le reste, les ports, les variables GET, l'ID de ressource, est crypté.

La seule mise en garde à cela est que le serveur de réception peut se déconnecter du chemin de demande complet, mais vous en avez le contrôle afin que vous puissiez protéger ces données comme bon vous semble.

Patrick
la source
3

L'authentification de base n'est pas un bon moyen de sécuriser votre API REST. J'ai expliqué les raisons de cette réponse .

Lorsque vous créez une API REST, vous implémentez le serveur de ressources en termes OAuth2. Tout ce que votre API doit faire est de valider que le jeton transmis avec la demande dans l' en-tête HTTP d'autorisation est valide et d'un émetteur de confiance. Consultez ce lien pour savoir comment implémenter la validation s'il n'y a pas de bibliothèque disponible.

La façon dont votre client acquiert le jeton du serveur d'autorisation dépend du type de client qu'il s'agit. N'oubliez pas que vous devez spécifier le type de client que vous allez utiliser lorsque vous enregistrez le client auprès du serveur d'autorisation.

Dans le cas d'une application Web parlant à votre serveur, elle pourrait utiliser le code d'autorisation . S'il s'agit d'un client non fiable comme une application mobile ou une application JavaScript, il doit utiliser la subvention implicite .

Pour les services principaux qui ne peuvent pas interagir avec un propriétaire de ressource, vous pouvez utiliser l' attribution des informations d'identification client . Pour les outils de ligne de commande, vous pouvez utiliser les informations d'identification du client ou l' octroi du mot de passe du propriétaire de la ressource .

Tout dépend du type de client que vous utilisez.

Enfin, la validation d'un jeton JWT se produit sur le serveur de ressources sans avoir à parler au serveur d'autorisation. Cela conduit à une meilleure architecture évolutive, puis à des solutions qui doivent rechercher des données privées pour chaque client.

MvdD
la source
1

C'est sécurisé ou pas sécurisé. Ni plus ni moins. Avoir base64 ne rend pas l'authentification de base (ou quoi que ce soit) plus sûr.

Il n'y a rien de mal à envoyer quoi que ce soit non crypté s'il utilise un canal crypté comme Https.

OAuth a plus de fonctionnalités, utilisez-le si vous en avez besoin. Pour toute autre chose, par exemple bancaire, l'utilisation de la réponse de défi de base est fine et sécurisée.

imel96
la source
0

Je pense que vous devez d'abord comprendre les terminologies. Vous comparez - Autorisation et signature numérique

OAuth est un standard ouvert pour l' autorisation , où, comme le fait Amazon (selon l'article et les détails fournis dans votre question), crée une signature numérique valide qui donne au destinataire (ici Amazon) une raison de croire que le message a été créé par un utilisateur connu l'expéditeur, que l'expéditeur ne peut nier avoir envoyé le message ( authentification et non-répudiation)

Pour quel mécanisme d'autorisation utiliser, cela dépend plus ou moins de votre cas d'utilisation.

Voici ce que vous pouvez trouver sur StackOverflow ici :

Authentification de base qui nécessite un hachage très simple pour calculer le seul en-tête requis - OAuth est sans aucun doute une authentification plus coûteuse. La chose importante à réaliser est que les deux mécanismes d'authentification ont des objectifs entièrement différents. L'authentification de base sert à authentifier un client auprès d'une application principale. OAuth est destiné à autoriser un tiers à accéder aux données client à partir d'une application principale. Les deux ont leur place et le choix de l'un doit être dicté par le cas d'utilisation particulier de la mise en œuvre.

Et voici un autre article intéressant comparant les deux.

L'authentification de base sur SSL est en fait assez responsable, d'un point de vue de sécurité simpliste. Lorsque nous sommes confrontés à des noms d'utilisateur et des mots de passe, l'authentification de base est une solution courante car elle est si facile à implémenter. La transmission des informations d'identification est cryptée via SSL et l'utilisation de l'en-tête «Authorization» est omniprésente dans les clients et les systèmes HTTP.

Guanxi
la source