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.

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 enTrusted 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: Trusted 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 muestra, primero debes completar los siguientes pasos:


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

Antes de ejecutar los ejemplos de código, asigna el valor s3nsapis.fr a la variable de entorno GOOGLE_CLOUD_UNIVERSE_DOMAIN.

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 muestra, primero debes completar los siguientes pasos:

/**
 * 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 muestra, primero debes completar los siguientes pasos:


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 muestra, primero debes completar los siguientes pasos:

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 Trusted 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:

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.

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. Consulta la documentación del producto para identificar los roles necesarios para invocar el servicio de destino. Asigna estos roles a la cuenta de servicio en el servicio de destino.
  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
    

Siguientes pasos