Obtener un token de ID

En esta página se describen algunas formas de obtener 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 el tiempo de vida de los tokens de ID, consulta Tokens de ID.

Los tokens de ID tienen un servicio o una aplicación específicos para los que se pueden usar, que se especifica mediante el valor de su reclamación aud. En este documento se usa el término servicio de destino para hacer referencia al servicio o la aplicación en los que se puede usar el token de ID para autenticarse.

Cuando obtengas 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:

Si necesitas que una aplicación que no está alojada enGoogle Cloudacepte un token de ID, probablemente puedas usar estos métodos. Sin embargo, debes determinar qué reclamaciones de tokens de ID 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 asociada, el servidor de metadatos del servicio asociado suele proporcionar un token de ID. El servidor de metadatos genera tokens de ID para la cuenta de servicio asociada. 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 tu código se esté ejecutando en los siguientes servicios: Google Cloud

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

curl

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

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

PowerShell

Sustituye AUDIENCE por el URI del servicio de destino, como 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 este código de ejemplo, debes instalar la biblioteca de cliente de autenticación 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

Para ejecutar este código de ejemplo, debes instalar la biblioteca de autenticación de Google para 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 este código de ejemplo, debes instalar la biblioteca de Python de autenticación de Google.


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

Para ejecutar este código de ejemplo, debes instalar la biblioteca de autenticación de Google 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 Google Cloud servicios te ayudan a llamar a otros servicios. Estos servicios conectados pueden ayudar a determinar cuándo se realiza la llamada o a gestionar un flujo de trabajo que incluya llamar al servicio. Los siguientes servicios pueden incluir automáticamente un token de ID, con el valor adecuado para la reclamación aud, cuando inicien una llamada a un servicio que requiera un token de ID:

Cloud Scheduler
Cloud Scheduler es un programador de tareas cron de nivel empresarial totalmente gestionado. Puedes configurar Cloud Scheduler para que incluya un token de ID o un token de acceso cuando invoque otro servicio. Para obtener más información, consulta Usar la autenticación con destinos HTTP.
Cloud Tasks
Cloud Tasks permite gestionar la ejecución de tareas distribuidas. Puedes configurar una tarea para que incluya un token de ID o un token de acceso cuando llame a un servicio. Para obtener más información, consulta Usar 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 que incluya un token de ID con un mensaje. Para obtener más información, consulta el artículo sobre la autenticación de suscripciones de inserción.
Flujos de trabajo
Workflows es una plataforma de orquestación totalmente gestionada que ejecuta servicios en el orden que definas: un flujo de trabajo. Puedes definir un flujo de trabajo para incluir un token de ID o un token de acceso cuando invoque otro servicio. Para obtener más información, consulta Hacer solicitudes autenticadas desde un flujo de trabajo.

Generar un token de ID suplantando la identidad de una cuenta de servicio

La suplantación de cuentas de servicio permite que un principal genere credenciales de duración reducida para una cuenta de servicio de confianza. La entidad principal puede usar estas credenciales para autenticarse como la cuenta de servicio.

Para que una entidad principal pueda suplantar a una cuenta de servicio, debe tener un rol de gestión de identidades y accesos en esa cuenta de servicio que le permita hacerlo. Si la cuenta principal es otra cuenta de servicio, puede parecer más fácil proporcionar los permisos necesarios directamente a esa cuenta de servicio y permitirle suplantar su propia identidad. Esta configuración, conocida como suplantación de identidad, crea una vulnerabilidad de seguridad, ya que permite que la cuenta de servicio cree un token de acceso que se puede actualizar indefinidamente.

La suplantación de cuentas de servicio siempre debe implicar a dos principales: un principal que representa al llamante y la cuenta de servicio que se está suplantando, denominada cuenta de servicio con privilegios.

Para generar un token de ID suplantando la identidad de una cuenta de servicio, sigue este proceso general.

Para obtener instrucciones detalladas, consulta el artículo Crear un token de ID.

  1. Identifica o crea una cuenta de servicio que tenga los privilegios.

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

    • En el caso de los servicios de Cloud Run, asigna el rol Invocador de Cloud Run (roles/run.invoker).
    • En el caso de las funciones de Cloud Run, asigna el rol Invocador de Cloud Functions (roles/cloudfunctions.invoker).
    • Para otros servicios de destino, consulta la documentación del producto correspondiente.
  3. Identifica la entidad de seguridad que realizará la suplantación y configura las credenciales predeterminadas de la aplicación (ADC) para usar las credenciales de esta entidad de seguridad.

    En los entornos de desarrollo, la entidad de seguridad suele ser la cuenta de usuario que has proporcionado a ADC mediante la CLI de gcloud. Sin embargo, si se ejecuta en un recurso con una cuenta de servicio asociada, la cuenta de servicio asociada es el principal.

  4. Asigna al principal el rol Creador de tokens de identidad de OpenID Connect de cuenta de servicio (roles/iam.serviceAccountOpenIdTokenCreator).

  5. Usa la API Credentials de IAM para generar el token de ID de la cuenta de servicio autorizada.

    Haz los cambios siguientes:

    • AUDIENCE: el URI del servicio de destino. Por ejemplo, http://www.example.com.
    • SERVICE_ACCOUNT_EMAIL: la dirección de correo de la cuenta de servicio con privilegios.
    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d '{"audience": "AUDIENCE", "includeEmail": "true"}' \
    https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateIdToken
    

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

Puedes usar la CLI de gcloud para obtener un token de ID de las credenciales de tu usuario que se pueda usar con cualquier servicio o función de Cloud Run que el llamador tenga los permisos de gestión de identidades y accesos necesarios para invocar. Este token no funcionará en ninguna otra aplicación.

Siguientes pasos