Obtén un token de ID

En esta página, se describen algunas formas de adquirir un token de ID de OpenID Connect (OIDC) firmado por Google. Necesitas un token de ID firmado por Google para los siguientes casos prácticos de autenticación:

Para obtener información sobre el contenido y la duración de los tokens de ID, consulta Tokens de ID.

Los tokens de ID tienen un servicio o aplicación para los que se pueden usar, especificados por el valor de su reclamación aud. En esta página, se usa el término servicio de destino para hacer referencia a la aplicación o el servicio en el que se puede usar el token de ID a fin de autenticarse.

Cuando obtienes el token de ID, puedes incluirlo en un encabezado Authorization en la solicitud al servicio de destino.

Métodos para obtener un token de ID

Hay varias formas de obtener un token de ID. En esta página, se describen los siguientes métodos:

Cloud Run y Cloud Functions proporcionan formas específicas del servicio de obtener un token de ID. Para obtener más información, consulta Autentícate en aplicaciones alojadas en Cloud Run o Cloud Functions.

Si necesitas que una aplicación no alojada en Google Cloud acepte un token de ID, es probable que puedas usar estos métodos, pero debes determinar qué reclamaciones del token requiere la aplicación.

Obtener un token de ID del servidor de metadatos

Cuando tu código se ejecuta en un recurso que puede tener una cuenta de servicio adjunta, el servidor de metadatos para el servicio asociado puede, en la mayoría de los casos, proporcionar un token de ID. El servidor de metadatos genera tokens de ID para la cuenta de servicio conectada. No puedes obtener un token de ID basado en las credenciales de usuario del servidor de metadatos.

Puedes obtener un token de ID del servidor de metadatos cuando el código se ejecuta en los siguientes servicios de Google Cloud:

Para recuperar un token de ID del servidor de metadatos, consulta el extremo de identidad de la cuenta de servicio, como se muestra en este ejemplo.

curl

Reemplaza AUDIENCE por el URI del servicio de destino, por ejemplo, http://www.example.com.

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

PowerShell

Reemplaza AUDIENCE por el URI del servicio de destino, por ejemplo, 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

Para ejecutar esta muestra de código, debes instalar la biblioteca cliente de la API de Google para 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

Para ejecutar esta muestra de código, debes instalar la biblioteca de Python de 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.")

Rita

A fin de ejecutar esta muestra de código, debes instalar la Biblioteca de Google Auth para 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

Usar un servicio de conexión para generar un token de ID

Algunos servicios de Google Cloud te ayudan a llamar a otros. Estos servicios de conexión pueden ayudar a determinar cuándo se realiza la llamada o administrar un flujo de trabajo que incluya la llamada al servicio. Los siguientes servicios pueden incluir automáticamente un token de ID, con el valor apropiado para la reclamación aud, cuando inician una llamada a un servicio que requiere un token de ID:

Cloud Scheduler
Cloud Scheduler es un programador de trabajos cron de nivel empresarial completamente administrado. Puedes configurar Cloud Scheduler para que incluya un token de ID o de acceso cuando invoque a otro servicio. Para obtener más información, consulta Usa la autenticación con destinos de HTTP.
Cloud Tasks
Cloud Tasks te permite administrar la ejecución de tareas distribuidas. Puedes configurar una tarea para que incluya un token de ID o de acceso cuando llame a un servicio. Para obtener más información, consulta Usa tareas de destino HTTP con tokens de autenticación.
Pub/Sub
Pub/Sub permite la comunicación asíncrona entre servicios. Puedes configurar Pub/Sub para incluir un token de ID con un mensaje. Para obtener más detalles, consulta Autenticación para suscripciones de envío.
Workflows
Workflows es una plataforma de organización completamente administrada que ejecuta servicios en el orden que defines: un flujo de trabajo. Puedes definir un flujo de trabajo para incluir un token de ID o de acceso cuando invoque a otro servicio. Para obtener más información, consulta Realiza solicitudes autenticadas desde un flujo de trabajo.

Generar un token de ID mediante la suplantación de una cuenta de servicio

El robo de identidad de cuentas de servicio permite que una principal genere credenciales de corta duración para una cuenta de servicio confiable. Luego, la principal puede usar estas credenciales para autenticarse como la cuenta de servicio.

Antes de que una principal pueda actuar en nombre de una cuenta de servicio, debe tener un rol de IAM en esa cuenta de servicio que habilite el robo de identidad. Si la principal es en sí misma otra cuenta de servicio, podría parecer más fácil proporcionar los permisos necesarios directamente a esa cuenta de servicio y habilitarla para que se haga pasar por ella misma. Esta configuración, conocida como autosuplantación, crea una vulnerabilidad de seguridad, porque permite que la cuenta de servicio cree un token de acceso que pueda actualizarse a perpetuidad.

El robo de identidad de la cuenta de servicio siempre debe incluir dos principales: una principal que represente al emisor y la cuenta de servicio que se está suplantando, llamada “cuenta de servicio con privilegios”.

Para generar un token de ID en nombre de una cuenta de servicio, usa el siguiente proceso general.

Para obtener instrucciones paso a paso, consulta Crea un token de ID.

  1. Identifica o crea una cuenta de servicio para que sea la cuenta de servicio con privilegios. Otorga a esa cuenta de servicio el rol de IAM necesario en el servicio de destino:

    • Para los servicios de Cloud Run, otorga el rol de Cloud Run Invoker (roles/run.invoker).
    • Para Cloud Functions, otorga el rol Cloud Functions Invoker (roles/cloudfunctions.invoker).
    • Para otros servicios de destino, consulta la documentación del producto del servicio.
  2. Identifica el principal que realizará el robo de identidad y configura las Credenciales predeterminadas de la aplicación (ADC) para usar las credenciales de este principal.

    Para los entornos de desarrollo, el principal suele ser la cuenta de usuario que proporcionaste a ADC mediante la CLI de gcloud. Sin embargo, si ejecutas en un recurso con una cuenta de servicio adjunta, la cuenta de servicio adjunta es el principal.

  3. Otorga a el rol principal de creador de tokens de identidad de OpenID Connect de la cuenta de servicio (roles/iam.serviceAccountOpenIdTokenCreator).

  4. Usa la API de credenciales de IAM a fin de generar el token de ID para la cuenta de servicio autorizada.

Genera un token de ID genérico para desarrollo con Cloud Run y Cloud Functions

Puedes usar la CLI de gcloud a fin de obtener un token de ID para las credenciales de usuario que se puede usar con cualquier servicio de Cloud Run o función de Cloud Functions que el emisor tenga los permisos de IAM necesarios para invocar. Este token no funcionará para ninguna otra aplicación.

Generar un token de ID con un proveedor de identidad externo

La generación de un token de ID con un proveedor de identidad externo usa la federación de Workload Identity, que te permite establecer una relación entre Google Cloud y tu proveedor de identidad externo. Luego, puedes usar las credenciales que proporciona tu proveedor de identidad externo para generar tokens de ID o tokens de acceso que se pueden usar en Google Cloud.

A fin de generar un token de ID para las credenciales proporcionadas desde un proveedor de identidad externo, sigue estos pasos:

  1. Identifica o crea una cuenta de servicio a fin de proporcionar los roles de IAM necesarios para llamar al servicio de destino.

    Se recomienda crear una cuenta de servicio específicamente para este propósito y proporcionarle solo el rol necesario. Este enfoque sigue el principio de privilegio mínimo.

  2. Identifica los roles necesarios para invocar el servicio de destino. Otorga estos roles a la cuenta de servicio en el servicio de destino:

    • Para los servicios de Cloud Run, otorga el rol Cloud Run Invoker (roles/run.invoker).
    • Para Cloud Functions, otorga el rol Cloud Functions Invoker (roles/cloudfunctions.invoker).
    • Para otros servicios de destino, consulta la documentación del producto del servicio.
  3. Configura la federación de Workload Identity para tu proveedor de identidad como se describe en Configura la federación de Workload Identity.

  4. Sigue las instrucciones en Otorga permisos a identidades externas para actuar en nombre de una cuenta de servicio con la cuenta de servicio que configuraste en los pasos anteriores como la cuenta de servicio que se suplantará.

  5. Usa la API de REST para obtener un token de corta duración, pero, para el último paso, usa el método generateIdToken en su lugar para obtener un token de 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
    

    Reemplaza lo siguiente:

    • SERVICE_ACCOUNT_EMAIL: La dirección de correo electrónico de la cuenta de servicio
    • AUDIENCE: el público del token, como la aplicación o el servicio al que se accederá usando el token

¿Qué sigue?