Comment puis-je vérifier un jeton d'accès à l'API d'authentification Google?

134

Comment puis-je vérifier un jeton d'accès d'authentification Google?

Je dois en quelque sorte interroger Google et 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 Google Authentication Api :: OAuth Authentication for Web Applications peut être utilisé pour demander des données à une gamme de services Google. Il n'est pas clair 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 basée sur des jetons. Un jeton sera retourné lors de la fourniture d'un nom d'utilisateur et d'un mot de passe valides ou lors de la fourniture d'un jeton tiers à partir de 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 en utilisant son compte Google. Cela sera ensuite étendu pour inclure les comptes Yahoo, les fournisseurs OpenID de confiance, etc.

Exemple schématique d'accès basé sur Google:

texte alternatif 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 que je ne connais peut-être même jamais.

Par conséquent, je ne peux pas faire confiance au jeton fourni à l'API à l'étape 3. Il sera fourni avec l'adresse e-mail du compte Google correspondant.

Je dois en quelque sorte interroger Google et 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 que quelqu'un 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 de compte Gmail.

La documentation Google indique clairement comment, avec un jeton d'accès, les données peuvent être récupérées à partir d'un certain nombre de services Google. Rien ne semble indiquer comment vous pouvez vérifier si un jeton d'accès donné est valide en premier lieu.

Mettre à jour Le jeton est valide pour N services Google. Je ne peux pas essayer un jeton contre un service Google comme moyen de le vérifier car je ne saurai pas quel sous-ensemble de tous les services Google un utilisateur donné utilise réellement.

De plus, je n'utiliserai jamais le jeton d'accès d'authentification Google pour accéder à des services Google, simplement pour vérifier qu'un utilisateur supposé de Google est réellement qui il prétend être. S'il y a une autre façon de faire cela, je suis heureux d'essayer.

Jon Cram
la source
Sur quel service d'authentification spécifique porte cette question (OAuth, AuthSub, applications installées, ...)? Veuillez fournir un lien plus détaillé.
Martin v.Löwis
@Martin v. Löwis: Le service «Authentification OAuth pour les applications Web» - J'ai mis à jour le début de la question pour refléter cela. Merci de l'avoir signalé!
Jon Cram
un article intéressant sur la vérification de la clé Google pourrait donner plus d'informations groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
dotjoe

Réponses:

138

Pour la vérification de l'utilisateur, publiez simplement le jeton d'accès en tant que accessToken, publiez-le et obtenez la réponse

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken

vous pouvez également essayer dans la barre d'adresse des navigateurs, utiliser httppost et la réponse en 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 du accessToken. vous pouvez vérifier les identifiants de portée dans ce lien

Mise à jour: Nouvel article sur l'API comme ci-dessous

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

La réponse sera comme

 {
 // These six fields are included in all Google ID Tokens.
 "iss": "https://accounts.google.com",
 "sub": "110169484474386276334",
 "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
 "iat": "1433978353",
 "exp": "1433981953",

 // These seven fields are only included when the user has granted the "profile" and
 // "email" OAuth scopes to the application.
 "email": "[email protected]",
 "email_verified": "true",
 "name" : "Test User",
 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
 "given_name": "Test",
 "family_name": "User",
 "locale": "en"
}

Pour plus d'informations, https://developers.google.com/identity/sign-in/android/backend-auth

Vinoj John Hosan
la source
11
Il existe une version plus récente pour oauth2 de google - v3. Voir l'exemple ici: developer.google.com/identity/sign-in/android/backend-auth
AlikElzin-kilaka
30

vous pouvez vérifier un jeton d'accès d'authentification Google en utilisant ce point de terminaison:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token>

Il s'agit du point de terminaison de validation Google V3 OAuth AccessToken, vous pouvez vous référer au document google ci-dessous: (Dans l' OAUTH 2.0 ENDPOINTSonglet)

https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token

Nick Tsai
la source
Pour la documentation du backend - la source de la documentation est ici
eton_ceb
26

Ok, la plupart des réponses sont valides mais pas tout à fait exactes. 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'identifiant 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/

Remco
la source
3
Plus de votes positifs s'il vous plaît! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
Moritz Schmitz contre Hülst
Oui! ppl sont ddos-ing google s'ils appellent simplement google pour obtenir des informations sur les jetons
datdinhquoc
Vous ne pouvez pas faire cela avec les jetons d'accès Google, car ce ne sont pas des JWT. Vérifiez stackoverflow.com/questions/48623656/…
DanielJaramillo
18
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;
    }
}
ahmed
la source
2
Cette réponse est presque toujours valable. Cependant, Issued_to ne semble plus être défini. developer.google.com/accounts/docs/…
frostymarvelous
6

Réponse de flux de code Google oauth en plus des access_tokenretours id_tokenqui contiennent des informations utiles pour la validation sous forme cryptée.

Une chose qui rend les jetons d'identification utiles est le fait que vous pouvez les transmettre à différents composants de votre application. Ces composants peuvent utiliser un jeton d'identification comme mécanisme d'authentification léger authentifiant l'application et l'utilisateur. Mais avant de pouvoir utiliser les informations du jeton d'identification ou de vous y fier comme une affirmation que l'utilisateur s'est authentifié, vous devez le valider.

La validation d'un jeton d'identification nécessite plusieurs étapes:

  • Vérifiez que le jeton d'identification est un JWT correctement signé avec une clé publique Google appropriée.
  • Vérifiez que la valeur aud dans le jeton d'ID est égale à l'ID client de votre application.
  • Vérifiez que la valeur de iss dans le jeton d'identification est égale à accounts.google.com ou https://accounts.google.com .
  • Vérifiez que l'heure d'expiration (exp) du jeton d'identification n'est pas passée.
  • Si vous avez transmis un paramètre hd dans la demande, vérifiez que le jeton d'ID a une revendication hd qui correspond à votre domaine hébergé Google Apps.

Le lien https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken contient des exemples de code pour la validation des jetons d'identification.

Voir également /security/37818/why-use-openid-connect-instead-of-plain-oauth .

Vadzim
la source
1

Je dois en quelque sorte interroger Google et demander: Ce jeton d'accès est-il valide pour [email protected]?

Non. Tout ce dont vous avez besoin est de demander une connexion standard avec une connexion fédérée pour les utilisateurs de compte Google de votre domaine API. Et seulement après cela, vous pourrez comparer «ID utilisateur persistant» avec celui que vous avez de «l'interface publique».

La valeur de realm est utilisée sur la page Google Federated Login pour identifier le site demandeur auprès 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 «interface publique».

Et n'oubliez pas que l'utilisateur doit être sûr que votre API peut être fiable;) Donc, Google demandera à l'utilisateur s'il vous permet de vérifier son identité.

Malx
la source
1

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();
}
mpen
la source
0

Essayez de faire une demande authentifiée OAuth à l'aide de votre jeton à https://www.google.com/accounts/AuthSubTokenInfo . Ceci n'est documenté que pour fonctionner pour AuthSub, mais cela fonctionne également pour OAuth. Il ne vous dira pas à quel utilisateur le jeton est destiné, mais il vous indiquera pour quels services il est valide, et la demande échouera si le jeton est invalide ou a été révoqué.

Jonathan
la source
0

Un jeton d'accès OAuth arbitraire ne peut pas être utilisé pour l'authentification, car la signification du jeton est en dehors de la spécification OAuth Core. Il peut être destiné à un usage unique ou à une fenêtre d'expiration étroite, ou il peut fournir un accès que l'utilisateur ne souhaite pas donner. Il est également opaque et le consommateur OAuth qui l'a obtenu n'a peut-être jamais vu aucun type d'identifiant d'utilisateur.

Un fournisseur de services OAuth et un ou plusieurs consommateurs pourraient facilement utiliser 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 parlant uniquement OAuth Core ne peut pas fournir cela sans autre co- coordination avec un consommateur. La méthode REST AuthSubTokenInfo spécifique à Google, ainsi que l'identifiant de l'utilisateur, est proche, mais elle ne convient pas non plus, car elle pourrait invalider le jeton, ou le jeton pourrait être expiré.

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 au profit du RP. Il n'y a pas de jeton de longue durée ou autre handle spécifique à l'utilisateur qui pourrait être utilisé pour indiquer qu'un RP a authentifié avec succès un utilisateur avec un OP.

Une façon de vérifier une authentification précédente par rapport à un identifiant OpenID consiste simplement à effectuer à nouveau l'authentification, en supposant que le même agent utilisateur est utilisé. L'OP doit pouvoir renvoyer une assertion positive sans interaction de l'utilisateur (en vérifiant un cookie ou un certificat client, par exemple). L'OP est libre d'exiger une autre interaction de l'utilisateur, et le fera probablement si la demande d'authentification provient d'un autre domaine (mon OP me donne la possibilité de ré-authentifier ce RP particulier sans interagir à l'avenir). 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 se réauthentifier. Mais dans tous les cas, vous pourrez affirmer l'identité.

Karl Anderson
la source
OpenID 2.0 a été récemment déconseillé et désactivé par Google au profit d'OpenID Connect basé sur OAuth qui fournit des jetons d'identification vérifiables .
Vadzim