web-dev-qa-db-fra.com

Comment intégrer OAuth avec une application d'une seule page?

Lorsque j'utilise OAuth (2), j'ai besoin d'un point de terminaison de redirection dans mon application vers lequel le service offrant OAuth peut rediriger, une fois que j'ai été authentifié.

Comment gérer cela dans une application d'une seule page? Bien sûr, une redirection vers le service offrant OAuth n'est pas agréable ici, et il peut même ne pas être possible de rediriger.

Je sais que OAuth prend également en charge une génération de jetons basée sur le nom d'utilisateur/mot de passe. Cela fonctionne parfaitement avec un appel AJAX, mais nécessite que mon application d'une seule page demande un nom d'utilisateur et mot de passe.

Comment gérez-vous habituellement cela?

44
Golo Roden

La plupart du temps, une redirection est correcte même pour SPA car les utilisateurs n'aiment pas mettre leurs informations d'identification de service X sur un autre site Web que X. Une alternative sera d'utiliser une petite fenêtre contextuelle, vous pouvez vérifier ce que Discours le fait. À mon humble avis, une redirection est meilleure qu'une fenêtre contextuelle.

Google Certains fournisseurs prennent en charge le flux de propriétaires de ressources , ce que vous avez décrit comme l'envoi d'un nom d'utilisateur et d'un mot de passe, mais ce n'est pas agréable. Ce sont les problèmes que je vois:

  1. Demander des informations d'identification Google aux utilisateurs de votre site sera un refus pour certains utilisateurs.
  2. Les flux de propriétaires de ressources ont également besoin du client_secret et c'est quelque chose que vous ne devez PAS mettre dans votre javascript côté client. Si vous instanciez le flux du propriétaire de la ressource à partir de votre application côté serveur et que votre application n'est pas dans la même région géographique que l'utilisateur, l'utilisateur recevra un avertissement "hey quelqu'un essaie d'accéder avec vos informations d'identification depuis l'Inde".

OAuth décrit un flux côté client appelé flux implicite . En utilisant ce flux, vous n'avez besoin d'aucune interaction côté serveur et vous n'avez pas besoin du client_secret. Le fournisseur OAuth redirige vers votre application avec un "# access_token = xx". Il est appelé implicite car vous n'avez pas besoin d'échanger le code d'autorisation par jeton d'accès , vous obtenez un access_token directement.

Google implémente le flux implicite, vérifiez: tilisation d'OAuth2 pour les applications côté client .

Si vous souhaitez utiliser le flux implicite avec un fournisseur qui ne le prend pas en charge comme Github, vous pouvez utiliser un courtier d'authentification comme Auth .

Avertissement: Je travaille pour Auth0.

47
José F. Romaniello

Ce que José F. Romaniello dit est correct. Cependant, votre question est large et je pense donc que les conclusions proposées ne sont que des généralités à ce stade.

État de l'application

Par exemple, sans savoir à quel point l'état de votre application est complexe au moment où vous souhaitez autoriser vos utilisateurs à se connecter, personne ne peut savoir avec certitude si l'utilisation d'une redirection est même pratique . Considérez que vous pourriez être disposé à laisser l'utilisateur se connecter très tard dans son utilisation de workflow/application, à un moment où votre application contient l'état que vous ne voulez vraiment pas sérialiser et enregistrer sans raison valable. Sans parler d'écrire du code pour le reconstruire.

Remarque: Vous verrez de nombreux conseils pour simplement ignorer cela sur le Web. En effet, de nombreuses personnes stockent la majeure partie de l'état de leur application dans le stockage de session côté serveur et très peu sur leur client (léger). Parfois par erreur, parfois cela a vraiment du sens - assurez-vous que cela le soit pour vous si vous choisissez de l'ignorer. Si vous développez un client lourd, ce n'est généralement pas le cas.

Boîtes de dialogue contextuelles

Je me rends compte que les popups ont une mauvaise réputation sur le web à cause de tous leurs abus, mais il faut considérer les bonnes utilisations. Dans ce cas, ils remplissent exactement les mêmes fonctions que dialogues de confiance dans d'autres types de systèmes (pensez à Windows UAC, fd.o polkit, etc.). Ces interfaces se rendent toutes reconnaissables et utilisent les fonctionnalités de leur plate-forme sous-jacente pour s'assurer qu'elles ne peuvent pas être usurpées et que l'entrée ou l'affichage ne peuvent pas être interceptés par l'application non privilégiée. Le parallèle exact est que le navigateur chrome et en particulier le cadenas de certificat ne peut pas être usurpé, et que la politique d'origine unique empêche l'application d'accéder au DOM du popup. Interaction entre la boîte de dialogue (popup ) et l'application peut se produire en utilisant messagerie croisée ou autres techniques .

C'est probablement le moyen optimal, au moins jusqu'à ce que les navigateurs normalisent en quelque sorte l'autorisation de privilège, si jamais ils le font. Même dans ce cas, les processus d'autorisation pour certains fournisseurs de ressources peuvent ne pas correspondre à des pratiques standardisées, donc des dialogues personnalisés flexibles comme nous le voyons aujourd'hui peuvent être nécessaires.

Transitions de même fenêtre

Dans cet esprit, il est vrai que l'esthétique derrière une popup est subjective. À l'avenir, les navigateurs pourraient fournir des API pour autoriser le chargement d'un document sur une fenêtre existante sans décharger le document existant, puis permettre au nouveau document de décharger et de restaurer le document précédent. La question de savoir si l'application "cachée" continue de fonctionner ou est gelée (semblable à la façon dont les technologies de virtualisation peuvent geler les processus) est un autre débat. Cela permettrait la même procédure que celle que vous obtenez avec les popups. Il n'y a aucune proposition de faire cela que je sache.

Remarque: Vous pouvez simuler cela en rendant en quelque sorte tout l'état de votre application facilement sérialisable, et en ayant une procédure qui le stocke et le restaure dans/depuis le stockage local (ou un serveur distant). Vous pouvez ensuite utiliser des redirections à l'ancienne. Comme implicite au début, cela est potentiellement très intrusif pour le code de l'application.

Onglets

Une autre alternative est bien sûr d'ouvrir un nouvel onglet à la place, de communiquer avec lui exactement comme vous le feriez avec une fenêtre contextuelle, puis de le fermer de la même manière.

Sur la prise des informations d'identification de l'utilisateur à partir de l'application non privilégiée

Bien sûr, cela ne peut fonctionner que si vos utilisateurs vous font suffisamment confiance pour ne pas envoyer les informations d'identification à votre serveur (ou partout où ils ne veulent pas qu'ils finissent). Si vous open-source votre code et faites des builds/minimisation déterministes, il est théoriquement possible pour les utilisateurs d'auditer ou de faire auditer le code par quelqu'un, puis de vérifier automatiquement que vous n'avez pas falsifié la version d'exécution - gagnant ainsi leur confiance. L'outillage pour le faire sur le Web est AFAIK inexistant.

Cela étant dit, vous souhaitez parfois utiliser OAuth avec un fournisseur d'identité sous votre contrôle/autorité/marque. Dans ce cas, toute cette discussion est théorique - l'utilisateur vous fait déjà confiance.

Conclusion

En fin de compte, cela revient à (1) l'épaisseur de votre client et (2) à quoi vous voulez que l'UX soit.

21
tne

OAuth2 dispose de 4 types de subventions a.k.a., chacun servant un objectif spécifique:

  • Code d'autorisation (celui auquel vous avez fait allusion, qui nécessite une redirection)
  • Implicite
  • Informations d'identification du client
  • Informations d'identification du mot de passe du propriétaire de la ressource

La réponse courte est: utilisez le flux implicite.

Pourquoi? Le choix d'un type de flux ou d'octroi dépend du fait que n'importe quelle partie de votre code peut rester privée, et est donc capable de stocker une clé secrète. Si oui, vous pouvez choisir le flux OAuth2 le plus sécurisé - Authorization Code, sinon vous devrez faire des compromis sur un flux OAuth2 moins sécurisé. par exemple, pour une application d'une seule page (SPA) qui sera Implicit flow.

Client Credential le flux ne fonctionne que si le service Web et l'utilisateur sont la même entité, c'est-à-dire que le service Web ne sert que cet utilisateur spécifique, tandis que Resource Owner Password Credential le flux est le moins sécurisé et utilisé en dernier recours, car l'utilisateur doit fournir ses informations de connexion au service.

Pour bien comprendre la différence entre le flux Implicit recommandé et Authorization Code flow (celui auquel vous avez fait allusion et qui nécessite une redirection), jetez un œil au flux côte à côte:

Comparing 'Implicit' and 'Authorization Code' flow side-by-side

Ce diagramme est tiré de: https://blog.oauth.io/introduction-oauth2-flow-diagrams/

1
nethsix