L'authentification avec OAuth2 pour une application *et* un site web
Je suis le développement d'un site web qui est principalement accessible via une application, et je veux utiliser OAuth2 pour l'enregistrement de l'utilisateur et l'authentification. Puisque c'est une application Android je vais commencer à utiliser Google OAuth2 choses, car il fournit un décent de l'INTERFACE utilisateur sur Android.
Google déclare que "Vous pouvez choisir d'utiliser Google, le système d'authentification comme un moyen d'externaliser l'authentification de l'utilisateur de votre application. Cela peut éliminer le besoin de créer, de maintenir et de sécuriser un nom d'utilisateur et le mot de passe du magasin." qui est ce que je veux faire. Cependant quand je vais à travers tous leurs exemples et autres joyeusetés, je ne peux que trouver des choses à propos d'avoir un site web ou une application authentifier un utilisateur des services de Google.
Et en effet, quand je vais enregistrer mon application ("client") auprès de Google OAuth2 il y a des options pour le site web de clients et "installé" clients " (c'est à dire une application mobile), mais pas les deux. Je peux créer deux clients différents, mais j'ai lu le OAuth2 projet et je pense qu'il y aura un problème, que je vais maintenant expliquer.
Voici comment j'ai fait envisagent de travail:
- Utilisateur demande MyApp d'accéder à ses données privées.
- Application utilise Android
AccountManager
classe pour demander un jeton d'accès de Google Api. - Android dit à l'utilisateur "de L'app 'MyApp' veut accéder à vos Informations de Base sur Google. Est-ce ok?"
- Utilisateur dit oui.
AccountManager
se connecte à Google OAuth2 serveur en utilisant les informations d'identification stockées sur le téléphone et demande un jeton d'accès.- Jeton d'accès (qui suit la ligne verte) est retourné.
AccountManager
retourne le jeton d'accès à MyApp.- MyApp envoie une requête à l'Monsite pour l'utilisateur des données privées, y compris le jeton d'accès.
- Monsite besoin de vérifier l'utilisateur, en utilisant le jeton d'accès. Il valide le jeton comme décrit ici, Google, "Google, est-ce jeton valide?".
- Maintenant, ce que je voulez à arriver, c'est que Google dit "Oui, celui qui vous l'a donnée est bien celle de l'utilisateur.", mais ce que je pense que se passera réellement (basé sur le OAuth2 projet de Google et de la documentation), c'est qu'il va dire "c'est Pas possible! Ce jeton n'est valable que pour MyApp, et vous êtes Monsite. GTFO!".
Alors, comment dois-je faire cela? Et s'il vous PLAÎT ne dites pas "Utiliser OpenID" ou "Ne pas utiliser OAuth2" ou d'autres de même inutile de réponses. Oh, et je tiens vraiment à garder à l'aide de la belle AccountManager
de l'INTERFACE utilisateur plutôt que de la merde popup WebView
s
Modifier
Provisoire de la réponse (j'en ferai part si ça marche!) de Nikolay est qu'il faut réellement le travail, et les serveurs de Google ne sera pas un souci où le jeton d'accès de provenance. Semble un peu peu pour moi, mais je vais voir si ça marche!!!
Mise à jour
J'ai mis en œuvre ce modèle avec Facebook au lieu de Google et il fonctionne tout à fait. Le OAuth2 serveur n'a pas de soins où le jeton d'accès vient de. Au moins, Facebook ne veut pas, donc je suppose que Google ne veut pas non plus.
À la lumière de cela, il est une très mauvaise idée de stocker des jetons d'accès! Mais nous ne voulons pas avoir à frapper Facebook/les serveurs de Google pour vérifier l'authentification pour chaque demande car il va ralentir. Probablement la meilleure chose à faire est d'ajouter un cookie d'authentification pour votre site que vous avez la main quand leur jeton d'accès est validé, mais d'une façon plus simple est de ne traiter que le jeton d'accès comme un mot de passe et de stocker une table de hachage de il. Vous n'avez pas besoin de sel, soit depuis les jetons d'accès sont vraiment vraiment long. Si les étapes ci-dessus deviennent quelque chose comme:
9. Monsite besoin de vérifier l'utilisateur, en utilisant le jeton d'accès. D'abord, il vérifie son cache de hachage valide les jetons d'accès. Si la valeur de hachage de la clé cryptographique est trouvé, il sait que l'utilisateur est authentifié. Sinon, il vérifie avec Google comme décrit ici, Google, "Google, est-ce jeton valide?".
10. Si Google dit le jeton d'accès n'est pas valide, nous indiquent à l'utilisateur de GTFO. Sinon, Google dit "Oui, c'est un utilisateur valide" et nous, consultez notre enregistrés l'utilisateur de la base de données. Si ce nom d'utilisateur Google (ou Facebook id si vous utilisez Facebook) n'est pas trouvé, nous pouvons créer un nouvel utilisateur. Puis nous cache la valeur de hachage du jeton d'accès.
- Curieux - fait au-dessus de l'approche de travailler pour vous à la fin?
- Je n'ai même pas encore mise en oeuvre, désolé!
- Voir mise à jour question: Il a travaillé au moins pour Facebook.
- J'ai mis en place cette façon, il est de travail. De l'API Google, Google Play sur Android, et de ré-utiliser le jeton sur le côté serveur dans mon Spring3 app.
- +1 pour le bien expliqué question, y compris très utile diagramme. Voudrais donner un autre +1 pour le partage des résultats...
- Merci. Une mise à jour, je n'ai pas d'ajouter: facebook fait recommandons de stocker les jetons d'accès dans la base de données, puisque vous en avez besoin pour faire des trucs sur le facebook de serveurs (en supposant que vous voulez). Il n'est probablement pas une mauvaise idée de stocker les mots de passe, car si la base de données est compromise (et vous vous rendez compte), vous pouvez invalider tous la fuite des jetons d'accès.
Vous devez vous connecter pour publier un commentaire.
Vous avez probablement besoin d'OpenID Connect, qui utilise OAuth les jetons d'authentification. Comme pour
AccountManager
, l'actuel OAuth soutien est très orthodoxe, la nouvelle Google Play Services, prévue pour "bientôt" devrait, espérons que ce soit mieux. Voir ici pour un démo.J'ai posté juste une réponse similaires StackOverflow question.
Google appelle cela Applications Hybrides et explique comment une "Android app obtient l'accès hors connexion à Web back-end".
L'essentiel, c'est que vous aurez à passer un massé
scope
chaîne enGoogleAuthUtil.getToken
afin d'obtenir le retour d'un Code d'Autorisation (pas un OAuth2 Jeton). Que le Code d'Autorisation peut être passé à partir de votre application mobile sur votre serveur et d'être échangé pour un OAuth2 Jeton Jeton d'Actualisation, selon ce schéma.La
scope
paramètre doit ressembler à quelque chose comme ceci:com.google.android.gms.auth.GoogleAuthException: Unknown.
Aucune idée pourquoi? Est-il quelque chose de mal avec mon étendues? gist.github.com/lawloretienne/7351151Vous pouvez utiliser le jeton d'accès récupérées par l'application mobile n'importe où ailleurs. Lecteur SDK a une belle et simple d'intro qui va par le biais de la circulation sur https://developers.google.com/drive/quickstart-android
Au moins avec Google, le jeton d'accès expire par la suite. C'est pourquoi le android
AccountManager
a lainvalidateAuthToken
méthode--la mise en cache jeton d'accès a expiré, et vous devez dire à laAccountManager
à arrêter de vous donner à l'ancien et au lieu d'en obtenir un nouveau. Cela le rend un peu plus sûr de mettre en cache le jeton, le jeton lui-même ne vous donne pas éternelle accès en tant qu'utilisateur. Au lieu de cela, lorsque valable, il a simplement dit: "à un certain moment dans le passé récent, ce jeton a été acquis par une source de confiance."Voici un couple de choses que j'ai trouvé utile lorsque vous travaillez avec des jetons. La première est de Google tokeninfo point de terminaison. Le jeton est encodée en base64, JSON. Cela signifie qu'il n'est pas crypté, vous devez être sûr d'utiliser HTTPS pour la communication. Cependant, cela signifie également que vous pouvez examiner le jeton et avoir une meilleure idée de ce qui se passe.
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=
Si votre jeton a été "abcdef", vous accédez à:
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=abcdef
et Google serait de décompresser le jeton pour vous. C'est un simple objet JSON qui comprend un "expires_in" champ vous indiquant le nombre de secondes pendant lequel le jeton est toujours valide. À 6:03 dans la vidéo ci-dessous, vous pouvez voir l'déballé jeton:
https://developers.google.com/events/io/sessions/383266187
Que la vidéo comprend un aperçu complet de la situation de OAuth2 et il est bien la peine de regarder dans son intégralité si vous allez avoir affaire avec OAuth et des jetons. L'orateur traite également d'autres formes de Oauth2 jetons, qui ne sont pas des jetons d'accès, qui n'ont pas de date d'expiration.
Une autre ressource utile est le OAuth aire de Jeux. Cela vous permet de faire des choses de base comme les étendues, les demandes d', et obtenir des jetons. Ce lien semble fonctionner de façon sporadique, et sur Chrome j'ai dû installer le protocole Oauth aire de Jeux de l'app:
https://developers.google.com/oauthplayground/
Et voici un tutoriel par Tim Bray, le haut-parleur dans la vidéo, en expliquant comment utiliser les jetons d'accès de communiquer à un serveur à partir d'une application pour Android. Cela a été utile pour moi parce que j'ai commencé à comprendre comment les différentes choses dans l'API de Google Console de travailler ensemble:
http://android-developers.blogspot.in/2013/01/verifying-back-end-calls-from-android.html
En ce qui concerne la réponse exacte à votre question, je dirais que vous n'avez jamais besoin de mettre en cache le jeton d'accès sur le serveur. Comme expliqué dans la Vérification de l'Extrémité Arrière des Appels à partir d'Android lien ci-dessus, la vérification d'un jeton est presque toujours un rapide appel statique, ce qui signifie qu'il n'est aucune raison de mettre en cache les jetons:
Enfin, vous pouvez en effet utiliser le
AccountManager
pour obtenir des jetons d'accès. Toutefois, Google maintenant, au lieu d'encourager l'utilisation de laGoogleAuthUtil
classe dans le Jeu des Services de bibliothèque à la place:En un mot, quelle est la différence de l'utilisation de OAuth2 demande getAuthToken et getToken
Ici noter le commentaire de Tim Bray, le même gars encore une fois à partir de liens ci-dessus, en disant qu'ils sont en train de mettre leurs efforts en
GoogleAuthUtil
route. Notez, cependant, que cela signifie que vous serait limité à Google d'authentification. Je crois que leAccountManager
peut être utilisée pour obtenir, par exemple, un Facebook jeton de la place--pas le cas avecGoogleAuthUtil
.com.google.android.gms.auth.GoogleAuthException: Unknown.
Aucune idée pourquoi? Est-il quelque chose de mal avec mon étendues? gist.github.com/lawloretienne/7351151il décrit exactement ce que vous voulez:
https://developers.google.com/identity/protocols/CrossClientAuth
Quand on avait besoin de faire quelque chose de similaire sur un non-google OAuth Serveur, nous avons gardé les jetons dans une DB sur le site. L'application serait alors d'utiliser des services web à la demande le jeton lorsque nécessaires à la demande de données.
L'utilisateur pourrait faire de OAuth inscription soit sur le web ou d'une application. Ils ont partagé le même token d'application, de sorte qu'ils pourraient partager le même jeton d'accès. Après l'enregistrement, nous permettrait de stocker l'accès et l'actualisation des jetons dans la base de données pour l'utilisation de n'importe quelle application, il faut.
AccountManager
utiliser le même id de client comme mon site, dans la mesure où je peux dire. Aussi comment vous authentifier l'application quand elle demande à votre serveur web pour le jeton d'accès utilisateur? Des acclamations.