Obtenir un jeton d'ID

Cette page décrit plusieurs façons d'obtenir un jeton d'identification OpenID Connect (OIDC) signé par Google. Vous avez besoin d'un jeton d'ID signé par Google pour les cas d'utilisation d'authentification suivants :

Pour en savoir plus sur le contenu et la durée de vie des jetons d'ID, consultez la section Jetons d'ID.

Les jetons d'ID ont un service ou une application spécifique pour lesquels ils peuvent être utilisés, spécifiés par la valeur de leur revendication aud. Cette page utilise le terme service cible pour désigner le service ou l'application auxquels le jeton d'ID peut être utilisé pour s'authentifier.

Lorsque vous obtenez le jeton d'ID, vous pouvez l'inclure dans un en-tête Authorization de la requête adressée au service cible.

Méthodes permettant d'obtenir un jeton d'ID

Il existe différentes manières d'obtenir un jeton d'ID. Cette page décrit les méthodes suivantes :

Cloud Run et Cloud Functions fournissent des méthodes spécifiques au service pour obtenir un jeton d'ID. Pour en savoir plus, consultez la section S'authentifier auprès d'applications hébergées sur Cloud Run ou Cloud Functions.

Si vous avez besoin qu'un jeton d'ID soit accepté par une application non hébergée sur Google Cloud, vous pouvez probablement utiliser ces méthodes, mais vous devez déterminer quels sont les jetons d'ID requis par l'application.

Obtenir un jeton d'ID à partir du serveur de métadonnées

Lorsque votre code est exécuté sur une ressource à laquelle un compte de service est associé, le serveur de métadonnées du service associé peut généralement fournir un jeton d'ID. Le serveur de métadonnées génère des jetons d'ID pour le compte de service associé. Vous ne pouvez pas obtenir de jeton d'ID en fonction des identifiants utilisateur à partir du serveur de métadonnées.

Vous pouvez obtenir un jeton d'ID à partir du serveur de métadonnées lorsque votre code s'exécute sur les services Google Cloud suivants :

Pour récupérer un jeton d'ID à partir du serveur de métadonnées, vous interrogez le point de terminaison de l'identité du compte de service, comme indiqué dans cet exemple.

curl

Remplacez AUDIENCE par l'URI du service cible, par exemple http://www.example.com.

curl -H "Metadata-Flavor: Google" \
  'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE'

PowerShell

Remplacez AUDIENCE par l'URI du service cible, par exemple http://www.example.com.

$value = (Invoke-RestMethod `
  -Headers @{'Metadata-Flavor' = 'Google'} `
  -Uri "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE")
$value

Java

Pour exécuter cet exemple de code, vous devez installer la bibliothèque cliente des API Google pour Java.


import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.IdTokenCredentials;
import com.google.auth.oauth2.IdTokenProvider;
import com.google.auth.oauth2.IdTokenProvider.Option;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;

public class IdTokenFromMetadataServer {

  public static void main(String[] args) throws IOException, GeneralSecurityException {
    // TODO(Developer): Replace the below variables before running the code.

    // The url or target audience to obtain the ID token for.
    String url = "https://example.com";

    getIdTokenFromMetadataServer(url);
  }

  // Use the Google Cloud metadata server to create an identity token and add it to the
  // HTTP request as part of an Authorization header.
  public static void getIdTokenFromMetadataServer(String url) throws IOException {
    // Construct the GoogleCredentials object which obtains the default configuration from your
    // working environment.
    GoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();

    IdTokenCredentials idTokenCredentials =
        IdTokenCredentials.newBuilder()
            .setIdTokenProvider((IdTokenProvider) googleCredentials)
            .setTargetAudience(url)
            // Setting the ID token options.
            .setOptions(Arrays.asList(Option.FORMAT_FULL, Option.LICENSES_TRUE))
            .build();

    // Get the ID token.
    // Once you've obtained the ID token, you can use it to make an authenticated call to the
    // target audience.
    String idToken = idTokenCredentials.refreshAccessToken().getTokenValue();
    System.out.println("Generated ID token.");
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	"golang.org/x/oauth2/google"
	"google.golang.org/api/idtoken"
	"google.golang.org/api/option"
)

// getIdTokenFromMetadataServer uses the Google Cloud metadata server environment
// to create an identity token and add it to the HTTP request as part of an Authorization header.
func getIdTokenFromMetadataServer(w io.Writer, url string) error {
	// url := "http://www.example.com"

	ctx := context.Background()

	// Construct the GoogleCredentials object which obtains the default configuration from your
	// working environment.
	credentials, err := google.FindDefaultCredentials(ctx)
	if err != nil {
		return fmt.Errorf("failed to generate default credentials: %w", err)
	}

	ts, err := idtoken.NewTokenSource(ctx, url, option.WithCredentials(credentials))
	if err != nil {
		return fmt.Errorf("failed to create NewTokenSource: %w", err)
	}

	// Get the ID token.
	// Once you've obtained the ID token, you can use it to make an authenticated call
	// to the target audience.
	_, err = ts.Token()
	if err != nil {
		return fmt.Errorf("failed to receive token: %w", err)
	}
	fmt.Fprintf(w, "Generated ID token.\n")

	return nil
}

Node.js

/**
 * TODO(developer):
 *  1. Uncomment and replace these variables before running the sample.
 */
// const targetAudience = 'http://www.example.com';

const {GoogleAuth} = require('google-auth-library');

async function getIdTokenFromMetadataServer() {
  const googleAuth = new GoogleAuth();

  const client = await googleAuth.getIdTokenClient(targetAudience);

  // Get the ID token.
  // Once you've obtained the ID token, you can use it to make an authenticated call
  // to the target audience.
  await client.idTokenProvider.fetchIdToken(targetAudience);
  console.log('Generated ID token.');
}

getIdTokenFromMetadataServer();

Python

Pour exécuter cet exemple de code, vous devez installer la bibliothèque Python Google Auth.


import google
import google.oauth2.credentials
from google.auth import compute_engine
import google.auth.transport.requests

def idtoken_from_metadata_server(url: str):
    """
    Use the Google Cloud metadata server in the Cloud Run (or AppEngine or Kubernetes etc.,)
    environment to create an identity token and add it to the HTTP request as part of an
    Authorization header.

    Args:
        url: The url or target audience to obtain the ID token for.
            Examples: http://www.example.com
    """

    request = google.auth.transport.requests.Request()
    # Set the target audience.
    # Setting "use_metadata_identity_endpoint" to "True" will make the request use the default application
    # credentials. Optionally, you can also specify a specific service account to use by mentioning
    # the service_account_email.
    credentials = compute_engine.IDTokenCredentials(
        request=request, target_audience=url, use_metadata_identity_endpoint=True
    )

    # Get the ID token.
    # Once you've obtained the ID token, use it to make an authenticated call
    # to the target audience.
    credentials.refresh(request)
    # print(credentials.token)
    print("Generated ID token.")

Ruby

Pour exécuter cet exemple de code, vous devez installer la bibliothèque Google Auth pour Ruby.

require "googleauth"

##
# Uses the Google Cloud metadata server environment to create an identity token
# and add it to the HTTP request as part of an Authorization header.
#
# @param url [String] The url or target audience to obtain the ID token for
#   (e.g. "http://www.example.com")
#
def auth_cloud_idtoken_metadata_server url:
  # Create the GCECredentials client.
  id_client = Google::Auth::GCECredentials.new target_audience: url

  # Get the ID token.
  # Once you've obtained the ID token, you can use it to make an authenticated call
  # to the target audience.
  id_client.fetch_access_token
  puts "Generated ID token."

  id_client.refresh!
end

Utiliser un service de connexion pour générer un jeton d'ID

Certains services Google Cloud vous aident à appeler d'autres services. Ces services de connexion peuvent vous aider à déterminer quand l'appel est effectué ou à gérer un workflow incluant l'appel du service. Les services suivants peuvent automatiquement inclure un jeton d'ID, avec la valeur appropriée pour la revendication aud, lorsqu'ils appellent un service nécessitant un jeton d'ID :

Cloud Scheduler
Cloud Scheduler est un planificateur de tâches Cron entièrement géré, spécialement conçu pour les entreprises. Vous pouvez configurer Cloud Scheduler de manière à inclure un jeton d'ID ou un jeton d'accès lorsqu'il appelle un autre service. Pour en savoir plus, consultez Utiliser l'authentification avec des cibles HTTP.
Cloud Tasks
Cloud Tasks vous permet de gérer l'exécution de tâches distribuées. Vous pouvez configurer une tâche de manière à inclure un jeton d'ID ou un jeton d'accès lorsqu'elle appelle un service. Pour en savoir plus, consultez la section Utiliser des tâches HTTP Target avec des jetons d'authentification.
Pub/Sub
Pub/Sub permet la communication asynchrone entre les services. Vous pouvez configurer Pub/Sub de façon à inclure un jeton d'ID avec un message. Pour en savoir plus, consultez la section Authentification pour les abonnements push.
Workflows
Workflows est une plate-forme d'orchestration entièrement gérée qui exécute des services dans un ordre que vous définissez : un workflow. Vous pouvez définir un workflow de manière à inclure un jeton d'ID ou un jeton d'accès lorsqu'il appelle un autre service. Pour plus d'informations, consultez la page Effectuer des requêtes authentifiées à partir d'un workflow.

Générer un jeton d'ID en empruntant l'identité d'un compte de service

Emprunter l'identité d'un compte de service permet à un compte principal de générer des identifiants éphémères pour un compte de service approuvé. Le compte principal peut ensuite utiliser ces identifiants pour s'authentifier en tant que compte de service.

Pour qu'un compte principal puisse emprunter l'identité d'un compte de service, il doit disposer d'un rôle IAM permettant d'emprunter une identité sur ce compte de service. Si le compte principal est lui-même un autre compte de service, il peut sembler plus simple de fournir les autorisations requises directement à ce compte de service et de lui permettre d'emprunter une identité. Cette configuration, appelée "auto-emprunt d'identité", crée une faille de sécurité, car elle permet au compte de service de créer un jeton d'accès pouvant être actualisé à l'infini.

L'emprunt d'identité d'un compte de service doit toujours impliquer deux comptes principaux : le compte principal qui représente l'appelant, et le compte de service dont l'identité est empruntée, appelé compte de service porteur de privilèges.

Vous pouvez appliquer le processus général suivant pour générer un jeton d'ID en empruntant l'identité d'un compte de service.

Pour obtenir des instructions détaillées, consultez la section Créer un jeton d'ID.

  1. Identifiez ou créez un compte de service en tant que compte de service avec privilège. Attribuez à ce compte de service le rôle IAM requis sur le service cible :

    • Pour les services Cloud Run, attribuez le rôle Demandeur Cloud Run (roles/run.invoker).
    • Pour Cloud Functions, attribuez le rôle Demandeur Cloud Functions (roles/cloudfunctions.invoker).
    • Pour les autres services cibles, consultez la documentation du produit concerné.
  2. Identifiez le compte principal qui effectuera l'emprunt d'identité et configurez les ADC (Identifiants par défaut de l'application) pour utiliser les identifiants de ce compte principal.

    Pour les environnements de développement, le compte principal est généralement le compte utilisateur que vous avez fourni aux ADC en utilisant gcloud CLI. Toutefois, si l'exécution se déroule sur une ressource à laquelle un compte de service est associé, le compte de service associé est le compte principal.

  3. Attribuez au compte principal le rôle "Créateur de jetons d'identité OpenID Connect du compte de service" (roles/iam.serviceAccountOpenIdTokenCreator).

  4. Utilisez l'API IAM Credentials pour générer le jeton d'ID pour le compte de service autorisé.

Générer un jeton d'ID générique pour le développement avec Cloud Run et Cloud Functions

Vous pouvez utiliser gcloud CLI afin d'obtenir un jeton d'ID pour vos identifiants utilisateur, qui peut être utilisé avec n'importe quel service Cloud Run ou fonction Cloud pour lequel ou laquelle l'appelant dispose des autorisations IAM requises pour effectuer l'appel. Ce jeton ne fonctionnera avec aucune autre application.

Générer un jeton d'ID à l'aide d'un fournisseur d'identité externe

La génération d'un jeton d'ID à l'aide d'un fournisseur d'identité externe utilise la fédération d'identité de charge de travail, qui vous permet de configurer une relation entre Google Cloud et votre fournisseur d'identité externe. Vous pouvez ensuite utiliser les identifiants fournis par votre fournisseur d'identité externe pour générer des jetons d'ID ou des jetons d'accès pouvant être utilisés dans Google Cloud.

Pour générer un jeton d'ID pour les identifiants fournis par un fournisseur d'identité externe, procédez comme suit :

  1. Identifiez ou créez un compte de service afin de fournir les rôles IAM requis pour appeler le service cible.

    Il est recommandé de créer un compte de service spécifique à cet effet et de ne lui attribuer que le rôle requis. Cette approche suit le principe du moindre privilège.

  2. Identifiez les rôles requis pour appeler le service cible. Attribuez ces rôles au compte de service sur le service cible :

    • Pour les services Cloud Run, attribuez le rôle Demandeur Cloud Run (roles/run.invoker).
    • Pour Cloud Functions, attribuez le rôle Demandeur Cloud Functions (roles/cloudfunctions.invoker).
    • Pour les autres services cibles, consultez la documentation du produit concerné.
  3. Configurez la fédération d'identité de charge de travail pour votre fournisseur d'identité, comme décrit dans la section Configurer la fédération d'identité de charge de travail.

  4. Suivez les instructions de la section Autoriser des identités externes à emprunter l'identité d'un compte de service en utilisant le compte de service que vous avez configuré aux étapes précédentes en tant que compte de service dont l'identité doit être empruntée.

  5. Utilisez l'API REST pour acquérir un jeton de courte durée, mais pour la dernière étape, utilisez plutôt la méthode generateIdToken pour obtenir un jeton d'ID :

    Bash

    ID_TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateIdToken \
        -H "Content-Type: text/json; charset=utf-8" \
        -H "Authorization: Bearer $STS_TOKEN" \
        -d @- <<EOF | jq -r .token
        {
            "audience": "AUDIENCE"
        }
    EOF
    )
    echo $ID_TOKEN
    

    PowerShell

    $IdToken = (Invoke-RestMethod `
        -Method POST `
        -Uri "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateIdToken" `
        -Headers @{ "Authorization" = "Bearer $StsToken" } `
        -ContentType "application/json" `
        -Body (@{
            "audience" = "AUDIENCE"
        } | ConvertTo-Json)).token
    Write-Host $IdToken
    

    Remplacez les éléments suivants :

    • SERVICE_ACCOUNT_EMAIL : adresse e-mail du compte de service.
    • AUDIENCE : audience du jeton, telle que l'application ou le service auquel le jeton sera appliqué pour autoriser l'accès.

Étapes suivantes