Comment puis-je vérifier un jeton d'accès à l'authentification Google?
Je dois en quelque sorte interroger Google et lui demander: Le [jeton d'accès donné] est-il valide pour le compte Google [[email protected]]?
version courte:
Il est clair comment un jeton d'accès fourni via le Authentification Google Api :: OAuth Authentification pour les applications Web peut être utilisé pour demander des données à partir d'une plage Nous ne savons pas comment vérifier si un jeton d'accès donné est valide pour un compte Google donné. J'aimerais savoir comment.
Version longue:
Je développe une API qui utilise l'authentification par jeton. Un jeton sera renvoyé si un nom d'utilisateur + mot de passe valide a été fourni ou si un jeton tiers a été fourni par l'un des N services vérifiables.
L'un des services tiers sera Google, permettant à un utilisateur de s'authentifier auprès de mon service à l'aide de son compte Google. Cela sera étendu ultérieurement pour inclure les comptes Yahoo, les fournisseurs OpenID de confiance, etc.
Exemple schématique d'accès basé sur Google:
alt text http://webignition.net/images/figures/auth_figure002.png
L'entité 'API' est sous mon contrôle total. L'entité "interface publique" est toute application Web ou de bureau. Certaines interfaces publiques sont sous mon contrôle, d'autres ne le seront pas et d'autres encore, je ne les connais peut-être même jamais.
Par conséquent, je ne peux pas faire confiance au jeton fourni à l'API à l'étape 3. Celui-ci sera fourni avec l'adresse e-mail du compte Google correspondante.
Je dois en quelque sorte interroger Google et lui demander: Ce jeton d'accès est-il valide pour [email protected]?
Dans ce cas, [email protected] est l'identifiant unique du compte Google - l'adresse e-mail qu'une personne utilise pour se connecter à son compte Google. Cela ne peut pas être supposé être une adresse Gmail - quelqu'un peut avoir un compte Google sans avoir un compte Gmail.
La documentation de Google indique clairement comment, avec un jeton d'accès, les données peuvent être récupérées à partir de plusieurs services Google. Rien ne semble indiquer comment vous pouvez vérifier si un jeton d'accès donné est valide.
Mettre à jour Le jeton est valide pour N services Google. Je ne peux pas essayer un jeton contre un service Google pour le vérifier, car je ne saurai pas quel sous-ensemble de tous les services de Google utilise réellement un utilisateur donné.
De plus, je n'utiliserai jamais le jeton d'accès à l'authentification Google pour accéder à des services Google, simplement pour vérifier si un utilisateur supposé de Google est bien ce qu'il prétend être. S'il y a une autre façon de faire cela, je suis heureux d'essayer.
Pour vérifier l'utilisateur, il suffit d'envoyer le jeton d'accès en tant que accessToken, de le poster et d'obtenir la réponse.
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken
vous pouvez également essayer la barre d’adresse dans les navigateurs, utilisez https et la réponse dans Java également
la réponse sera comme
{
"issued_to": "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"audience": "xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"user_id": "xxxxxxxxxxxxxxxxxxxxxxx",
"scope": "https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com",
"expires_in": 3340,
"access_type": "offline"
}
La portée est l'autorisation donnée par accessToken. vous pouvez vérifier les identifiants de portée dans ce lien
vous pouvez vérifier un jeton d'accès à l'authentification Google à l'aide de ce noeud final:
https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token>
C’est Google V3 OAuth AccessToken validant le point de terminaison, vous pouvez vous reporter à partir du document Google ci-dessous: (Dans OAUTH 2.0 ENDPOINTS
Onglet)
https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token
function authenticate_google_OAuthtoken($user_id)
{
$access_token = google_get_user_token($user_id); // get existing token from DB
$redirecturl = $Google_Permissions->redirecturl;
$client_id = $Google_Permissions->client_id;
$client_secret = $Google_Permissions->client_secret;
$redirect_uri = $Google_Permissions->redirect_uri;
$max_results = $Google_Permissions->max_results;
$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$access_token;
$response_contacts = curl_get_responce_contents($url);
$response = (json_decode($response_contacts));
if(isset($response->issued_to))
{
return true;
}
else if(isset($response->error))
{
return false;
}
}
Ok, la plupart des réponses sont valables mais pas tout à fait correctes. L'idée de JWT est que vous pouvez valider le jeton sans avoir besoin de contacter l'émetteur à chaque fois. Vous devez vérifier l'id et vérifier la signature du jeton avec la clé publique connue du certificat que Google a utilisé pour signer le jeton.
Voir le prochain post pourquoi et comment faire cela.
http://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/
Google oauth réponse du flux de code en plus de access_token
retourne également id_token
qui contient des informations utiles pour la validation sous forme chiffrée.
Une chose qui rend les clés d’identité utiles est le fait que vous pouvez les transmettre à différents composants de votre application. Ces composants peuvent utiliser un jeton d'identification en tant que mécanisme d'authentification léger authentifiant l'application et l'utilisateur. Mais avant de pouvoir utiliser les informations contenues dans le jeton ID ou de vous y fier en tant qu'affirmation que l'utilisateur s'est authentifié, vous devez le valider.
La validation d'un jeton d'identification nécessite plusieurs étapes:
https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken le lien contient des exemples de code pour la validation des jetons ID.
Voir aussi https://security.stackexchange.com/questions/37818/why-use-openid-connect-instead-of-plain-oauth .
Je dois en quelque sorte interroger Google et lui demander: ce jeton d'accès est-il valide pour [email protected]?
Non. Tout ce dont vous avez besoin, c'est de demander une connexion standard avec connexion fédérée pour les utilisateurs de compte Google à partir de votre domaine d'API. Et seulement après cela, vous pourrez comparer "ID utilisateur persistant" avec celui que vous avez depuis "interface publique".
La valeur du domaine est utilisée sur la page de connexion fédérée de Google pour identifier le site demandeur à destination de l'utilisateur. Il est également utilisé pour déterminer la valeur de l'ID utilisateur persistant renvoyé par Google.
Vous devez donc appartenir au même domaine que "l'interface publique".
Et n'oubliez pas que l'utilisateur doit être sûr que votre API peut être approuvée;) Google demandera donc à l'utilisateur si cela vous permet de vérifier son identité.
Voici un exemple utilisant Guzzle :
/**
* @param string $accessToken JSON-encoded access token as returned by \Google_Client->getAccessToken() or raw access token
* @return array|false False if token is invalid or array in the form
*
* array (
* 'issued_to' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
* 'audience' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
* 'scope' => 'https://www.googleapis.com/auth/calendar',
* 'expires_in' => 3350,
* 'access_type' => 'offline',
* )
*/
public static function tokenInfo($accessToken) {
if(!strlen($accessToken)) {
return false;
}
if($accessToken[0] === '{') {
$accessToken = json_decode($accessToken)->access_token;
}
$guzzle = new \GuzzleHttp\Client();
try {
$resp = $guzzle->get('https://www.googleapis.com/oauth2/v1/tokeninfo', [
'query' => ['access_token' => $accessToken],
]);
} catch(ClientException $ex) {
return false;
}
return $resp->json();
}
Un jeton d'accès arbitraire OAuth ne peut pas être utilisé pour l'authentification, car sa signification est en dehors de la OAuth Core. Il pourrait être destiné à une fenêtre d’utilisation unique ou d’expiration limitée, ou elle peut fournir un accès que l’utilisateur ne souhaite pas donner. Elle est également opaque et le consommateur OAuth qui l’a obtenu ne l’a peut-être jamais vu identifiant utilisateur.
Un fournisseur de services OAuth et un ou plusieurs consommateurs pourraient utiliser facilement OAuth pour fournir un jeton d'authentification vérifiable, et il existe des propositions et des idées pour le faire, mais un fournisseur de services arbitraire ne parlant que OAuth Le noyau ne peut fournir cela sans autre coordination avec un consommateur. La méthode AuthSubTokenInfo spécifique à Google REST, ainsi que avec l'identifiant de l'utilisateur, est proche, mais cela ne convient pas non plus, car cela pourrait invalider le jeton ou le jeton pourrait expirer.
Si votre identifiant Google est un identifiant OpenId et que votre "interface publique" est une application Web ou peut appeler le navigateur de l'utilisateur, vous devriez probablement utiliser l'OpenID OP de Google.
OpenID consiste simplement à envoyer l'utilisateur à l'OP et à récupérer une assertion signée. L'interaction est uniquement à l'avantage du RP. Il n'y a pas de jeton de longue durée ni d'autre identificateur spécifique à l'utilisateur pouvant être utilisé pour indiquer qu'un RP a réussi à authentifier un utilisateur avec un OP.
Un moyen de vérifier une authentification antérieure par rapport à un identifiant OpenID consiste à effectuer une nouvelle authentification, en supposant que le même agent d'utilisateur est utilisé. Le PO doit pouvoir retourner une assertion positive sans interaction de l'utilisateur (en vérifiant par exemple un cookie ou un certificat client). L'OP est libre d'exiger une autre interaction de l'utilisateur, et probablement si la demande d'authentification provient d'un autre domaine (mon OP me donne la possibilité de réauthentifier ce RP en particulier sans interagir ultérieurement). Et dans le cas de Google, l'interface utilisateur par laquelle l'utilisateur est passé pour obtenir le jeton OAuth peut ne pas utiliser le même identifiant de session, de sorte que l'utilisateur devra s'authentifier à nouveau. Mais dans tous les cas, vous Serez capable de faire valoir l'identité.
Essayez de faire une demande authentifiée par OAuth en utilisant votre jeton pour https://www.google.com/accounts/AuthSubTokenInfo . Cela ne concerne que AuthSub, mais cela fonctionne pour OAuth aussi. Il ne vous dira pas à quel utilisateur le jeton est destiné, mais il indiquera les services pour lesquels il est valide, et la demande échouera si le jeton est invalide ou a été révoqué.