Utiliser OAuth 2.0 pour l'authentification serveur à serveur

<ph type="x-smartling> Pour en savoir plus, consultez Présentation de l'authentification dans la documentation Google Cloud Platform.

Le système Google OAuth 2.0 est compatible avec les interactions entre serveurs, par exemple celles entre une application Web et un service Google. Pour ce scénario, vous avez besoin d'un compte de service, qui appartient à votre application plutôt qu'à un utilisateur final individuel. Votre application appelle les API Google au nom du compte de service, de sorte que les utilisateurs ne sont pas directement impliqués. Ce scénario est parfois appelé "OAuth" à deux acteurs, "2LO". (Le terme associé "OAuth en trois étapes") désigne les scénarios dans lesquels votre application appelle les API Google au nom des utilisateurs finaux, et dans lesquels le consentement de l'utilisateur est parfois requis.

En règle générale, une application utilise un compte de service pour exploiter ses propres données plutôt que celles des utilisateurs à l'aide des API Google. Par exemple, une application qui utilise Google Cloud Datastore pour la persistance des données utilise un compte de service pour authentifier ses appels auprès de l'API Google Cloud Datastore.

Les administrateurs de domaine Google Workspace peuvent également accorder à des comptes de service une autorité à l'échelle du domaine d'accès aux données des utilisateurs au nom des utilisateurs du domaine.

Ce document décrit comment une application peut compléter le flux OAuth 2.0 de serveur à serveur à l'aide d'une bibliothèque cliente des API Google (recommandé) ou de HTTP.

Présentation

Pour prendre en charge les interactions de serveur à serveur, créez d'abord un compte de service pour votre projet dans le . Si vous souhaitez accéder aux informations sur les utilisateurs dans votre compte Google Workspace, déléguez l'accès au compte de service à l'échelle du domaine.

Votre application se prépare ensuite à passer des appels d'API autorisés à l'aide des identifiants du compte de service afin de demander un jeton d'accès au serveur d'authentification OAuth 2.0.

Enfin, votre application peut utiliser le jeton d'accès pour appeler les API Google.

Création d'un compte de service…

Les identifiants du compte de service incluent une adresse e-mail générée unique, et au moins une paire de clés publique/privée. Si la délégation au niveau du domaine est activée, un ID client fait également partie des identifiants du compte de service.

Si votre application s'exécute sur Google App Engine, un compte de service est configuré automatiquement lorsque vous créez votre projet.

Si votre application s'exécute sur Google Compute Engine, un compte de service est également configuré automatiquement lorsque vous créez votre projet, mais vous devez spécifier les champs d'application auxquels votre application doit accéder lorsque vous créez une instance Google Compute Engine. Pour en savoir plus, consultez la section Préparer une instance pour utiliser des comptes de service.

Si votre application n'est pas exécutée sur Google App Engine ni sur Google Compute Engine, vous devez obtenir ces identifiants dans le fichier . Pour générer les identifiants du compte de service ou afficher les identifiants publics que vous avez déjà générés, procédez comme suit:

Tout d'abord, créez un compte de service :

  1. Ouvrez le Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Cliquez sur Créer compte de service.
  4. Sous les détails du compte de service, saisissez un nom, ID, et une description pour le compte de service, puis cliquez sur Créer et continuer.
  5. Facultatif: Dans le cadre Accorde compte un service d' accès au projet, sélectionnez les rôles IAM pour accorder au compte de service.
  6. Cliquez sur Continuer.
  7. En option: Les utilisateurs de moins autoriser l' accès à ce compte de service, ajoutez les utilisateurs ou les groupes qui sont autorisés à utiliser et à gérer le compte de service.
  8. Cliquez sur Terminé.
  9. Cliquez sur Créer clé, puis cliquez sur Créer.

Ensuite, créez une clé de compte de service :

  1. Cliquez sur l'adresse e-mail du compte de service que vous avez créé.
  2. Cliquez sur l'onglet Clés.
  3. Dans la liste déroulante touche Ajouter, sélectionnez Créer une nouvelle clé.
  4. Cliquez sur Créer.

Votre nouvelle paire de clés publique/privée est générée et téléchargée sur votre machine ; elle sert de seule copie de la clé privée. Vous êtes responsable de le stocker en toute sécurité. Si vous perdez cette paire de clés, vous devrez en générer une nouvelle.

Vous pouvez revenir à API Console à tout moment pour afficher l'adresse e-mail, les empreintes de clé publique et d'autres informations, ou pour générer d'autres paires de clés publique/privée. Pour en savoir plus sur les identifiants du compte de service dans API Console, consultez la section Comptes de service du fichier d'aide API Console.

Notez l'adresse e-mail du compte de service et stockez le fichier de clé privée du compte de service à un emplacement accessible à votre application. Votre application en a besoin pour effectuer des appels d'API autorisés.

Délégation d'une autorité au niveau du domaine au compte de service

Si vous disposez d'un compte Google Workspace, un administrateur de l'organisation peut autoriser une application à accéder aux données des utilisateurs au nom des utilisateurs du domaine Google Workspace. Par exemple, une application qui ajoute des événements aux agendas de tous les utilisateurs d'un domaine Google Workspace via l'API Google Calendar peut utiliser un compte de service pour accéder à l'API Google Calendar au nom des utilisateurs. L'autorisation d'un compte de service d'accéder à des données pour le compte d'utilisateurs d'un domaine est parfois appelée "délégation d'autorité" au niveau du domaine.

Pour déléguer l'autorité au niveau du domaine à un compte de service, un super-administrateur du domaine Google Workspace doit procéder comme suit:

  1. Depuis la console d'administration Google Workspace de votre domaine, accédez à Menu principal > Sécurité et gt; Accès et contrôle des données > Commandes des API.
  2. Dans le volet Délégation au niveau du domaine, sélectionnez Gérer la délégation au niveau du domaine.
  3. Cliquez sur Add New (Ajouter nouveau).
  4. Dans le champ Client-ID (ID client), saisissez l'ID client du compte de service. Votre ID client de compte de service se trouve dans Service accounts page.
  5. Dans le champ Champs d'application OAuth (séparés par une virgule), saisissez la liste des champs d'application auxquels votre application doit être autorisée à accéder. Par exemple, si votre application nécessite un accès complet au niveau du domaine à l'API Google Drive et à l'API Google Calendar, saisissez https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Cliquez sur Autoriser.

Votre application est désormais autorisée à effectuer des appels d'API en tant qu'utilisateurs de votre domaine (pour les utilisateurs). Lorsque vous vous préparez à effectuer des appels d'API autorisés, vous spécifiez l'identité de l'utilisateur.

Préparer un appel d'API autorisé

Java

Une fois que vous avez obtenu l'adresse e-mail et la clé privée du client à partir de API Console, utilisez la bibliothèque cliente des API Google pour Java afin de créer un objet GoogleCredential à partir des identifiants du compte de service ainsi que des champs d'application auxquels votre application doit accéder. Exemple :

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Si vous développez une application sur Google Cloud Platform, vous pouvez utiliser les identifiants par défaut de l'application, ce qui simplifie le processus.

Déléguer une autorité au niveau du domaine

Si vous avez délégué un accès au compte de service à l'échelle du domaine et que vous souhaitez emprunter l'identité d'un compte utilisateur, spécifiez l'adresse e-mail du compte utilisateur avec la méthode createDelegated de l'objet GoogleCredential. Exemple :

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("user@example.com");

Utilisez l'objet GoogleCredential pour appeler les API Google dans votre application.

Python

Une fois que vous avez obtenu l'adresse e-mail et la clé privée du client à partir de API Console, utilisez la bibliothèque cliente des API Google pour Python pour effectuer les étapes suivantes:

  1. Créez un objet Credentials à partir des identifiants du compte de service et des champs d'application auxquels votre application doit accéder. Exemple :
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Si vous développez une application sur Google Cloud Platform, vous pouvez utiliser les identifiants par défaut de l'application, ce qui simplifie le processus.

  2. Déléguer une autorité au niveau du domaine

    Si vous avez délégué un accès au compte de service à l'échelle du domaine et que vous souhaitez emprunter l'identité d'un compte utilisateur, utilisez la méthode with_subject d'un objet ServiceAccountCredentials existant. Exemple :

    delegated_credentials = credentials.with_subject('user@example.org')

Utilisez l'objet Credentials pour appeler les API Google dans votre application.

HTTP/REST

Après avoir obtenu l'ID client et la clé privée à partir de API Console, votre application doit suivre les étapes suivantes:

  1. Créez un jeton Web JSON (JWT, Pronounce, Jot &quot) qui inclut un en-tête, un ensemble de revendications et une signature.
  2. Demandez un jeton d'accès au serveur d'autorisation Google OAuth 2.0.
  3. Gérez la réponse JSON renvoyée par le serveur d'autorisation.

Les sections suivantes décrivent comment réaliser ces étapes.

Si la réponse inclut un jeton d'accès, vous pouvez l'appeler via une API Google. (Si la réponse ne contient pas de jeton d'accès, il est possible que votre jeton JWT et votre requête de jeton ne soient pas correctement formés ou que le compte de service n'ait pas l'autorisation d'accéder aux champs d'application demandés.)

Lorsque le jeton d'accès expire, votre application génère un autre jeton JWT, le signe et demande un autre jeton d'accès.

Votre application de serveur utilise un jeton JWT pour demander un jeton au serveur d&#39;autorisation Google, puis utilise un jeton pour appeler un point de terminaison de l&#39;API Google. Aucun utilisateur final n&#39;est impliqué.

Le reste de cette section décrit les spécificités de la création d'un JWT, de la signature du JWT, de la formation de la requête de jeton d'accès et de la gestion de la réponse.

Créer un JWT

Un JWT se compose de trois parties: un en-tête, un ensemble de revendications et une signature. L'ensemble d'en-tête et l'ensemble de revendications sont des objets JSON. Ces objets JSON sont sérialisés au format UTF-8, puis encodés à l'aide de l'encodage Base64url. Cet encodage offre une résilience à tout changement de codage en raison d'opérations d'encodage répétées. L'en-tête, l'ensemble de revendications et la signature sont concaténés avec un point (.).

Un JWT se compose des éléments suivants:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

La chaîne de base pour la signature est la suivante:

{Base64url encoded header}.{Base64url encoded claim set}
Créer l'en-tête JWT

L'en-tête se compose de deux champs qui indiquent l'algorithme de signature et le format de l'assertion. Ces deux champs sont obligatoires, et chaque champ ne comporte qu'une seule valeur. Suite à l'introduction d'algorithmes et de formats supplémentaires, cet en-tête change en conséquence.

Les comptes de service reposent sur l'algorithme RSA-256 et le format du jeton JWT. Par conséquent, la représentation JSON de l'en-tête est la suivante:

{"alg":"RS256","typ":"JWT"}

La représentation Base64url de ceci est la suivante:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
Former l'ensemble de revendications JWT

L'ensemble de revendications JWT contient des informations sur le jeton JWT, y compris les autorisations demandées (champs d'application), la cible du jeton, l'émetteur, l'heure d'émission du jeton et sa durée de vie. La plupart des champs sont obligatoires. Comme l'en-tête JWT, l'ensemble de revendications JWT est un objet JSON et est utilisé pour le calcul de la signature.

Revendications obligatoires

Les revendications requises dans l'ensemble de revendications JWT sont présentées ci-dessous. Ils peuvent apparaître dans n'importe quel ordre dans l'ensemble de revendications.

Nom Description
iss Adresse e-mail du compte de service.
scope Liste des autorisations demandées par l'application, séparées par un espace.
aud Descripteur de la cible prévue de l'assertion. Lors de l'envoi d'une requête de jeton d'accès, la valeur est toujours https://oauth2.googleapis.com/token.
exp Heure d'expiration de l'assertion, spécifiée en secondes depuis le 1er janvier 1970 à 00:00:00 UTC. Cette valeur ne doit pas dépasser une heure après l'heure d'émission.
iat Heure à laquelle l'assertion a été émise, exprimée en secondes depuis 00:00:00 UTC, le 1er janvier 1970.

Vous trouverez ci-dessous la représentation JSON des champs obligatoires dans un ensemble de revendications JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Revendications supplémentaires

Dans certains cas d'entreprise, une application peut utiliser une délégation au niveau du domaine pour agir au nom d'un utilisateur spécifique d'une organisation. Ce type d'usurpation d'identité doit être accordé pour qu'une application puisse emprunter l'identité d'un utilisateur et est généralement géré par un super-administrateur. Pour en savoir plus, consultez la section Contrôler l'accès aux API avec la délégation au niveau du domaine.

Pour obtenir un jeton d'accès qui accorde à une application un accès délégué à une ressource, incluez l'adresse e-mail de l'utilisateur dans la revendication JWT définie comme valeur du champ sub.

Nom Description
sub Adresse e-mail de l'utilisateur pour lequel l'application demande un accès délégué.

Si une application n'est pas autorisée à emprunter l'identité d'un utilisateur, la réponse à une requête de jeton d'accès qui inclut le champ sub est considérée comme une erreur.

Vous trouverez ci-dessous un exemple d'ensemble de revendications JWT comprenant le champ sub:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Encodage de l'ensemble de revendications JWT

Tout comme l'en-tête JWT, l'ensemble de revendications JWT doit être sérialisé en UTF-8 et encodé en base64url-url. Vous trouverez ci-dessous un exemple de représentation JSON d'un ensemble de revendications JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Calculer la signature

Une signature Web JSON (JWS) est la spécification qui guide la mécanique pour générer la signature pour le JWT. L'entrée de la signature correspond au tableau d'octets du contenu suivant:

{Base64url encoded header}.{Base64url encoded claim set}

L'algorithme de signature figurant dans l'en-tête JWT doit être utilisé pour calculer la signature. Le seul algorithme de signature compatible avec le serveur d'autorisation Google OAuth 2.0 est RSA à l'aide de l'algorithme de hachage SHA-256. Cette valeur est exprimée par RS256 dans le champ alg de l'en-tête JWT.

Signez la représentation UTF-8 de l'entrée à l'aide de SHA256withRSA (également appelé RSASSA-PKCS1-V1_5-SIGN avec la fonction de hachage SHA-256) avec la clé privée obtenue à partir de Google API Console. Le résultat correspond à un tableau d'octets.

Cette signature doit ensuite être encodée en base64url. L'en-tête, l'ensemble de revendications et la signature sont concaténés avec un point (.). Le résultat est le JWT. Cela doit se présenter comme suit (ajout de sauts de ligne pour plus de clarté):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Vous trouverez ci-dessous un exemple de jeton JWT avant l'encodage Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Vous trouverez ci-dessous un exemple de jeton JWT signé et prêt à être transmis:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Envoyer la requête de jeton d'accès

Une fois le jeton JWT signé, l'application peut demander un jeton d'accès. Cette requête de jeton d'accès est une requête POST HTTPS, et le corps est encodé au format URL. L'URL est illustrée ci-dessous:

https://oauth2.googleapis.com/token

Les paramètres suivants sont requis dans la requête POST HTTPS:

Nom Description
grant_type Utilisez la chaîne suivante, encodée en URL si nécessaire : urn:ietf:params:oauth:grant-type:jwt-bearer
assertion Le JWT, y compris la signature.

Vous trouverez ci-dessous un fichier de vidage brut de la requête HTTPS POST utilisée dans une requête de jeton d'accès:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Vous trouverez ci-dessous la même requête, avec curl :

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Gérer la réponse

Si le jeton JWT et la requête de jeton d'accès sont correctement formés et que le compte de service est autorisé à effectuer l'opération, la réponse JSON du serveur d'autorisation inclut un jeton d'accès. Voici un exemple de réponse:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Les jetons d'accès peuvent être réutilisés au cours de la période spécifiée par la valeur expires_in.

Appeler des API Google

Java

Utilisez l'objet GoogleCredential pour appeler les API Google en procédant comme suit:

  1. Créez un objet de service pour l'API que vous souhaitez appeler à l'aide de l'objet GoogleCredential. Exemple :
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Envoyez des requêtes au service d'API à l'aide de l'interface fournie par l'objet de service. Par exemple, pour répertorier les instances des bases de données Cloud SQL dans l'exemple passionnant du projet example-123 :
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Utilisez l'objet Credentials autorisé pour appeler les API Google en procédant comme suit:

  1. Créez un objet de service pour l'API que vous souhaitez appeler. Pour créer un objet de service, appelez la fonction build avec le nom et la version de l'API, ainsi qu'avec l'objet Credentials autorisé. Par exemple, pour appeler la version 1bêta3 de l'API Cloud SQL Administration :
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Envoyez des requêtes au service d'API à l'aide de l'interface fournie par l'objet de service. Par exemple, pour répertorier les instances des bases de données Cloud SQL dans l'exemple passionnant du projet example-123 :
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Une fois que votre application a obtenu un jeton d'accès, vous pouvez l'utiliser pour appeler une API Google au nom d'un compte de service ou d'un compte utilisateur donné si le ou les niveaux d'accès requis par l'API vous ont été accordés. Pour ce faire, incluez le jeton d'accès dans une requête adressée à l'API en incluant un paramètre de requête access_token ou une valeur d'en-tête HTTP Authorization Bearer. Dans la mesure du possible, il est préférable d'utiliser l'en-tête HTTP, car les chaînes de requête sont généralement visibles dans les journaux du serveur. Dans la plupart des cas, vous pouvez utiliser une bibliothèque cliente pour configurer vos appels aux API Google (par exemple, lorsque vous appelez l'API Drive Files).

Vous pouvez essayer toutes les API Google et en consulter la portée sur OAuth 2.0 Playground.

Exemples de requêtes HTTP GET

Un appel vers le point de terminaison drive.files (API Drive Files) à l'aide de l'en-tête HTTP Authorization: Bearer peut se présenter comme suit. Notez que vous devez spécifier votre propre jeton d'accès:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Voici un appel vers la même API pour l'utilisateur authentifié à l'aide du paramètre de chaîne de requête access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Exemples curl

Vous pouvez tester ces commandes avec l'application de ligne de commande curl. Voici un exemple qui utilise l'option d'en-tête HTTP (méthode recommandée):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Vous pouvez également sélectionner l'option du paramètre de chaîne de requête:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Expiration des jetons d'accès

Les jetons d'accès émis par le serveur d'autorisation Google OAuth 2.0 expirent après la durée indiquée par la valeur expires_in. Lorsqu'un jeton d'accès expire, l'application doit générer un autre jeton JWT, le signer et demander un autre jeton d'accès.

Codes d'erreur JWT

Champ error Champ error_description Signification Résolution du problème
unauthorized_client Unauthorized client or scope in request. Si vous essayez d'utiliser la délégation au niveau du domaine, le compte de service n'est pas autorisé dans la console d'administration du domaine de l'utilisateur.

Assurez-vous que le compte de service est autorisé sur la page Délégation au niveau du domaine de la console d'administration pour l'utilisateur dans la revendication sub (champ).

Bien que cela prenne généralement quelques minutes, un délai maximal de 24 heures peut être nécessaire pour que l'autorisation soit appliquée à tous les utilisateurs de votre compte Google.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Un compte de service a été autorisé à l'aide de l'adresse e-mail du client plutôt que de l'ID client (numérique) dans la console d'administration. Sur la page Délégation au niveau du domaine de la console d'administration, supprimez le client et ajoutez-le à nouveau avec l'ID numérique.
access_denied (toute valeur) Si vous utilisez la délégation au niveau du domaine, un ou plusieurs niveaux d'accès demandés ne sont pas autorisés dans la console d'administration.

Assurez-vous que le compte de service est autorisé sur la page Délégation au niveau du domaine de la console d'administration pour l'utilisateur dans la revendication sub (champ) et qu'il inclut tous les champs d'application que vous demandez dans la revendication scope de votre jeton JWT.

Bien que cela prenne généralement quelques minutes, un délai maximal de 24 heures peut être nécessaire pour que l'autorisation soit appliquée à tous les utilisateurs de votre compte Google.

invalid_grant Not a valid email. L'utilisateur n'existe pas. Vérifiez que l'adresse e-mail indiquée dans la revendication sub (champ) est correcte.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Cela signifie généralement que l'heure système locale n'est pas correcte. Cela peut aussi se produire si la valeur exp est postérieure de plus de 65 minutes à la valeur iat ou si la valeur exp est inférieure à iat.

Assurez-vous que l'horloge du système sur lequel le JWT est généré est correcte. Si nécessaire, synchronisez votre temps avec Google NTP.

invalid_grant Invalid JWT Signature.

L'assertion JWT est signée avec une clé privée non associée au compte de service identifié par l'adresse e-mail du client, ou la clé utilisée a été supprimée, désactivée ou a expiré.

Sinon, l'assertion JWT peut ne pas être encodée correctement. Elle doit être encodée au format Base64, sans retour à la ligne ni marge intérieure équivalente.

Décodez l'ensemble de revendications JWT et vérifiez que la clé qui a signé l'assertion est associée au compte de service.

Essayez d'utiliser une bibliothèque OAuth fournie par Google pour vous assurer que le jeton JWT est généré correctement.

invalid_scope Invalid OAuth scope or ID token audience provided. Aucun niveau d'accès n'a été demandé (liste vide) ou l'un des champs d'application demandés n'existe pas (c'est-à-dire non valide).

Assurez-vous que la revendication scope (champ) du jeton JWT est renseignée et comparez les champs d'application qu'elle contient avec les champs d'application documentés des API que vous souhaitez utiliser, pour vous assurer qu'il n'y a aucune erreur ni faute de frappe.

Notez que la liste des champs d'application de la revendication scope doit être séparée par des espaces, et non des virgules.

disabled_client The OAuth client was disabled. La clé utilisée pour signer l'assertion JWT est désactivée.

Accédez à Google API Console, et sous IAM & Admin > Service Accounts, activez le compte de service qui contient l'ID de clé utilisé pour signer l'assertion.

Avenant: Autorisation du compte de service sans OAuth

Avec certaines API Google, vous pouvez effectuer des appels d'API autorisés à l'aide d'un jeton JWT signé directement en tant que jeton de support, au lieu d'un jeton d'accès OAuth 2.0. Dans la mesure du possible, vous pouvez éviter d'envoyer une requête réseau au serveur d'autorisation de Google avant d'effectuer un appel d'API.

Si l'API que vous souhaitez appeler a une définition de service publiée dans le dépôt GitHub des API Google, vous pouvez effectuer des appels d'API autorisés à l'aide d'un jeton JWT au lieu d'un jeton d'accès. Pour ce faire, procédez comme suit :

  1. Créez un compte de service comme décrit ci-dessus. Veillez à conserver le fichier JSON obtenu lorsque vous créez le compte.
  2. À l'aide d'une bibliothèque JWT standard, telle que celle trouvée sur jwt.io, créez un JWT avec un en-tête et une charge utile, comme dans l'exemple suivant :
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Dans le champ kid de l'en-tête, spécifiez l'ID de clé privée de votre compte de service. Vous pouvez trouver cette valeur dans le champ private_key_id du fichier JSON de votre compte de service.
    • Pour les champs iss et sub, spécifiez l'adresse e-mail de votre compte de service. Vous pouvez trouver cette valeur dans le champ client_email du fichier JSON de votre compte de service.
    • Dans le champ aud, spécifiez le point de terminaison de l'API. Exemple : https://SERVICE.googleapis.com/.
    • Pour le champ iat, spécifiez l'heure Unix actuelle et, pour le champ exp, spécifiez l'heure exactement 3 600 secondes plus tard, lorsque le JWT expirera.

Signez le JWT avec RSA-256 à l'aide de la clé privée située dans le fichier JSON de votre compte de service.

Exemple :

Java

Utilisez google-api-java-client et java-jwt :

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

Avec PyJWT :

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Appelez l'API en utilisant le JWT signé comme jeton de support :
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com