Utiliser OAuth 2.0 pour l'authentification serveur à serveur

Le système Google OAuth 2.0 est compatible avec les interactions entre serveurs, par exemple entre une application Web et un service Google. Pour ce scénario, vous avez besoin d'un compte de service, qui est un compte appartenant à votre application et non à 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 jambes" ou "2LO". (Le terme associé "OAuth en trois étapes" fait référence aux scénarios dans lesquels votre application appelle les API Google pour le compte 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 lorsqu'elle utilise des API Google pour travailler avec ses propres données plutôt qu'avec les données d'un utilisateur. Par exemple, une application qui utilise Google Cloud Datastore pour la persistance des données emploie un compte de service pour authentifier ses appels à l'API Google Cloud Datastore.

Les administrateurs de domaine Google Workspace peuvent également accorder aux comptes de service une autorité au niveau du domaine pour accéder aux données utilisateur pour le compte des utilisateurs du domaine.

Ce document explique comment une application peut effectuer 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 entre serveurs, commencez par créer un compte de service pour votre projet dans API Console. Si vous souhaitez accéder aux données utilisateur des utilisateurs de votre compte Google Workspace, déléguez l'accès au niveau du domaine au compte de service.

Votre application se prépare ensuite à effectuer des appels d'API autorisés en utilisant les identifiants du compte de service pour 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éer un compte de service

Les identifiants d'un compte de service incluent une adresse e-mail générée unique et au moins une paire de clés publiques/privées. 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. Toutefois, vous devez spécifier les niveaux d'accès dont votre application a besoin lorsque vous créez une instance Google Compute Engine. Pour en savoir plus, consultez Préparer une instance à utiliser des comptes de service.

Si votre application ne s'exécute pas sur Google App Engine ni Google Compute Engine, vous devez obtenir ces identifiants dans Google API Console. Pour générer des identifiants de 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 un compte de service .
  4. Sous Détails du compte de service , saisissez un nom, un ID et une description pour le compte de service, puis cliquez sur Créer et continuer .
  5. Facultatif : sous Accorder à ce compte de service l'accès au projet , sélectionnez les rôles IAM à accorder au compte de service.
  6. Cliquez sur Continuer .
  7. Facultatif : sous Accorder aux utilisateurs l'accès à ce compte de service , ajoutez les utilisateurs ou les groupes autorisés à utiliser et à gérer le compte de service.
  8. Cliquez sur Terminé .

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 Ajouter une clé , 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 ; il sert de seule copie de la clé privée. Vous êtes responsable de sa conservation en toute sécurité. Si vous perdez cette paire de clés, vous devrez en générer une nouvelle.

Vous pouvez revenir à l' 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 de compte de service dans API Console, consultez Comptes de service dans le fichier d'aide de API Console.

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

Déléguer l'autorité au niveau du domaine au compte de service

À l'aide d'un compte Google Workspace, un administrateur Workspace de l'organisation peut autoriser une application à accéder aux données utilisateur Workspace pour le compte des utilisateurs du domaine Google Workspace. Par exemple, une application qui se sert de l'API Google Agenda pour ajouter des événements aux agendas de tous les utilisateurs d'un domaine Google Workspace peut accéder à l'API Google Agenda pour le compte des utilisateurs via un compte de service. Le fait d'autoriser un compte de service à accéder aux données pour le compte d'utilisateurs d'un domaine est parfois appelé "délégation de l'autorité au niveau du domaine" à ce compte de service.

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

  1. Dans la console d'administration de votre domaine Google Workspace, accédez à Menu principal  > Sécurité > Contrôle des accès et 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 Ajouter.
  4. Dans le champ ID client, saisissez l'ID client du compte de service. Vous trouverez l'ID client de votre compte de service dans le 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 avoir accès. Par exemple, si votre application nécessite un accès complet au niveau du domaine à l'API Google Drive et à l'API Google Agenda, 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 Workspace (pour "usurper l'identité" des utilisateurs). Lorsque vous vous préparez à effectuer ces appels d'API délégués, vous spécifiez explicitement l'utilisateur à emprunter.

Préparer un appel d'API délégué

Java

Après avoir obtenu l'adresse e-mail du client et la clé privée à partir de API Console, utilisez la bibliothèque d'authentification Google pour Java afin de créer un objet GoogleCredentials à partir des identifiants du compte de service et des niveaux d'accès dont votre application a besoin. Exemple :

import com.google.auth.oauth2.GoogleCredentials;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredentials credentials = GoogleCredentials.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 peut simplifier le processus.

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

Si vous avez délégué l'accès au niveau du domaine au compte de service 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 GoogleCredentials. Par exemple :

GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("[email protected]");

Le code ci-dessus utilise l'objet GoogleCredentials pour appeler sa méthode createDelegated(). L'argument de la méthode createDelegated() doit être un utilisateur appartenant à votre compte Workspace. Le code qui effectue la requête utilisera ces identifiants pour appeler les API Google à l'aide de votre compte de service.

Python

Après avoir obtenu l'adresse e-mail du client et la clé privée à 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 avoir accès. 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 peut simplifier le processus.

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

    Si vous avez délégué l'accès au niveau du domaine au compte de service 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('[email protected]')

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 effectuer les étapes suivantes :

  1. Créez un jeton Web JSON (JWT, prononcé "jot") 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 expliquent comment effectuer ces étapes.

Si la réponse inclut un jeton d'accès, vous pouvez l'utiliser pour appeler une API Google. (Si la réponse n'inclut pas de jeton d'accès, il est possible que votre requête JWT et de jeton ne soit pas correctement formulée, ou que le compte de service ne soit pas autorisé à 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 serveur utilise un jeton JWT pour demander un jeton au serveur d'autorisation Google, puis utilise le jeton pour appeler un point de terminaison d'API Google. Aucun utilisateur final n'est impliqué.

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

Créer un jeton JWT

Un jeton JWT se compose de trois parties : un en-tête, un ensemble de revendications et une signature. L'en-tête et l'ensemble de revendications sont des objets JSON. Ces objets JSON sont sérialisés en octets UTF-8, puis encodés à l'aide de l'encodage Base64url. Cet encodage offre une résilience contre les modifications d'encodage dues à des 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 jeton JWT se compose comme suit :

{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}
Former l'en-tête JWT

L'en-tête se compose de trois champs qui indiquent l'algorithme de signature, le format de l'assertion et l'ID de clé de la clé de compte de service qui a été utilisée pour signer le jeton JWT. L'algorithme et le format sont obligatoires, et chaque champ ne comporte qu'une seule valeur. Cet en-tête changera en fonction des algorithmes et des formats supplémentaires qui seront introduits. L'ID de clé est facultatif. Si un ID de clé incorrect est spécifié, GCP essaiera toutes les clés associées au compte de service pour valider le jeton et le refusera si aucune clé valide n'est trouvée. Google se réserve le droit de refuser les jetons dont les ID de clé sont incorrects à l'avenir.

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

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

La représentation Base64url de ce code est la suivante :

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Former l'ensemble de revendications JWT

L'ensemble de revendications JWT contient des informations sur le jeton JWT, y compris les autorisations demandées (scopes), 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é dans le calcul de la signature.

Revendications requises

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, délimitées par des espaces.
aud Descripteur de la cible prévue de l'assertion. Lorsque vous demandez un jeton d'accès, cette 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 est limitée à une heure après l'heure d'émission.
iat Heure à laquelle l'assertion a été émise, spécifiée en secondes depuis le 1er janvier 1970 à 00:00:00 UTC.

La représentation JSON des champs requis dans un ensemble de revendications JWT est présentée ci-dessous :

{
  "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 la délégation à l'échelle du domaine pour agir au nom d'un utilisateur spécifique d'une organisation. L'autorisation d'effectuer ce type d'usurpation d'identité doit être accordée avant qu'une application puisse usurper l'identité d'un utilisateur. Elle est généralement gérée par un super-administrateur. Pour en savoir plus, consultez Contrôler l'accès à l'API à l'aide de 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 l'ensemble de revendications JWT en tant que 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 demande de jeton d'accès incluant le champ sub sera une erreur.

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

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "[email protected]",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Encoder l'ensemble de revendications JWT

Comme l'en-tête JWT, l'ensemble de revendications JWT doit être sérialisé en UTF-8 et encodé en base64url. 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
}
Calcul de la signature

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

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

L'algorithme de signature dans l'en-tête JWT doit être utilisé lors du calcul de la signature. Le seul algorithme de signature accepté par le serveur d'autorisation Google OAuth 2.0 est RSA utilisant l'algorithme de hachage SHA-256. Cela est exprimé sous la forme 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. La sortie sera un tableau d'octets.

La signature doit ensuite être encodée au format 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. Il doit être le suivant (sauts de ligne ajoutés pour plus de clarté) :

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

Voici un exemple de 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

Effectuer la demande de jeton d'accès

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

https://oauth2.googleapis.com/token

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

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

Vous trouverez ci-dessous un dump 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

Voici la même requête, utilisant 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 la requête de jeton d'accès et de JWT est correctement formulée 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 pendant la période spécifiée par la valeur expires_in.

Appeler des API Google

Java

Utilisez l'objet GoogleCredentials 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 GoogleCredentials. Exemple :
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credentials).build();
  2. Envoyez des requêtes au service d'API à l'aide de l'interface fournie par l'objet de service. Par exemple, pour lister les instances de bases de données Cloud SQL dans le projet exciting-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. Vous créez un objet de service en appelant la fonction build avec le nom et la version de l'API, ainsi que l'objet Credentials autorisé. Par exemple, pour appeler la version 1beta3 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 lister les instances de bases de données Cloud SQL dans le projet exciting-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 effectuer des appels à une API Google au nom d'un compte de service ou d'un compte utilisateur donné, si les niveaux d'accès requis par l'API ont été accordés. Pour ce faire, incluez le jeton d'accès dans une requête envoyé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, l'en-tête HTTP est préférable, car les chaînes de requête ont tendance à être 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 tester toutes les API Google et afficher leurs habilitations sur la page OAuth 2.0 Playground.

Exemples de requêtes HTTP GET

Un appel au point de terminaison drive.files (API Drive Files) à l'aide de l'en-tête HTTP Authorization: Bearer peut ressembler à ce qui 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 à 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

curl exemples

Vous pouvez tester ces commandes avec l'application en 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 utiliser l'option de 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 Procédure de résolution
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 (champ) sub.

Bien que l'autorisation soit généralement appliquée en quelques minutes, un délai maximal de 24 heures peut être nécessaire pour qu'elle 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, puis ajoutez-le de nouveau avec l'ID numérique.
access_denied (toute valeur) Si vous utilisez la délégation au niveau du domaine, un ou plusieurs des 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 à l'échelle du domaine de la console d'administration pour l'utilisateur dans la revendication (champ) sub et qu'il inclut tous les niveaux d'accès que vous demandez dans la revendication scope de votre JWT.

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

admin_policy_enforced (toute valeur) Le compte Google ne peut pas autoriser un ou plusieurs des niveaux d'accès demandés en raison des règles de son administrateur Google Workspace.

Pour en savoir plus sur la façon dont un administrateur peut restreindre l'accès à tous les niveaux d'accès ou aux niveaux d'accès sensibles et restreints jusqu'à ce que l'accès soit explicitement accordé à votre ID client OAuth, consultez l'article d'aide pour les administrateurs Google Workspace Contrôler quelles applications tierces et internes ont accès aux données Google Workspace.

invalid_client (toute valeur)

Le client OAuth ou le jeton JWT n'est pas valide ou est mal configuré.

Pour en savoir plus, consultez la description de l'erreur.

Assurez-vous que le jeton JWT est valide et qu'il contient les revendications correctes.

Vérifiez que le client OAuth et le compte de service sont correctement configurés et que vous utilisez la bonne adresse e-mail.

Vérifiez que le jeton JWT est correct et qu'il a été émis pour l'ID client dans la requête.

deleted_client (toute valeur)

Le client OAuth utilisé pour effectuer la requête a été supprimé. La suppression peut être manuelle ou automatique dans le cas des clients inutilisés . Les clients supprimés peuvent être restaurés dans les 30 jours suivant leur suppression. En savoir plus

Utilisez un ID client qui est toujours actif.

invalid_grant Not a valid email. Cet utilisateur n'existe pas. Vérifiez que l'adresse e-mail indiquée dans la revendication (champ) sub 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 également se produire si la valeur exp est supérieure à 65 minutes par rapport à la valeur iat, ou si la valeur exp est inférieure à la valeur iat.

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

invalid_grant Invalid JWT Signature.

L'assertion JWT est signée avec une clé privée qui n'est pas 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é.

Il est également possible que l'assertion JWT soit mal encodée. Elle doit être encodée en Base64, sans saut de ligne ni signe égal de remplissage.

Décodez l'ensemble de revendications JWT et vérifiez que la clé ayant 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 JWT est généré correctement.

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

Assurez-vous que la revendication (champ) scope du JWT est renseignée, puis comparez les champs d'application qu'elle contient avec les champs d'application documentés pour les API que vous souhaitez utiliser, afin de vous assurer qu'il n'y a pas d'erreurs ni de fautes de frappe.

Notez que la liste des niveaux d'accès dans la revendication scope doit être séparée par des espaces, et non par 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, puis sous IAM et administration > Comptes de service, activez le compte de service qui contient l'ID de clé utilisé pour signer l'assertion.

org_internal This client is restricted to users within its organization. L'ID client OAuth de la requête fait partie d'un projet limitant l'accès aux comptes Google dans une organisation Google Cloud spécifique.

Utilisez un compte de service de l'organisation pour vous authentifier. Confirmez la configuration du type d'utilisateur pour votre application OAuth.

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, plutôt qu'un jeton d'accès OAuth 2.0. Lorsque cela est possible, vous pouvez éviter d'avoir à envoyer une requête réseau au serveur d'autorisation de Google avant d'effectuer un appel d'API.

Si la définition de service de l'API que vous souhaitez appeler est 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 :

  1. Créez un compte de service comme décrit ci-dessus. Veillez à conserver le fichier JSON que vous obtenez lorsque vous créez le compte.
  2. À l'aide d'une bibliothèque JWT standard, telle que celle disponible sur jwt.io, créez un JWT avec un en-tête et une charge utile semblables à l'exemple suivant :
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "[email protected]",
      "sub": "[email protected]",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Pour le champ kid dans l'en-tête, spécifiez l'ID de la clé privée de votre compte de service. Vous trouverez 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 trouverez cette valeur dans le champ client_email du fichier JSON de votre compte de service.
    • Pour 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. Pour le champ exp, spécifiez l'heure exactement 3 600 secondes plus tard, lorsque le jeton JWT expirera.

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

Exemple :

Java

Utiliser google-auth-library-java et java-jwt :

import com.google.auth.oauth2.ServiceAccountCredentials;
...
GoogleCredentials credentials =
        GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = ((ServiceAccountCredentials) credentials).getPrivateKey();
String privateKeyId = ((ServiceAccountCredentials) credentials).getPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("[email protected]")
        .withSubject("[email protected]")
        .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': '[email protected]',
           'sub': '[email protected]',
           '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 jeton JWT signé comme jeton du porteur :
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com

Implémenter la protection multicompte

Pour protéger les comptes de vos utilisateurs, vous devez également implémenter la protection multi-comptes en utilisant le service de protection multi-comptes de Google. Ce service vous permet de vous abonner aux notifications d'événements de sécurité, qui fournissent à votre application des informations sur les modifications majeures apportées au compte utilisateur. Vous pouvez ensuite utiliser ces informations pour prendre des mesures en fonction de la manière dont vous décidez de répondre aux événements.

Voici quelques exemples de types d'événements envoyés à votre application par le service de protection multi-comptes de Google :

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

Pour en savoir plus sur l'implémentation de la protection multicompte et obtenir la liste complète des événements disponibles, consultez la page Protéger les comptes utilisateur avec la protection multicompte .