取得 ID 權杖

本頁說明取得 Google 簽署的 OpenID Connect (OIDC) ID 權杖的幾種方式。

如要瞭解 ID 權杖內容和生命週期,請參閱「ID 權杖」。

身分符記只能用於特定服務或應用程式,這類服務或應用程式是由符記的 aud 聲明值指定。本頁面使用「目標服務」一詞,是指可用於驗證 ID 權杖的服務或應用程式。

取得 ID 權杖後,您可以在向目標服務提出要求的 Authorization 標頭中加入該權杖。

取得 ID 權杖的方法

取得 ID 權杖的方式有很多種。本頁面說明下列方法:

如果應用程式並非託管於Trusted Cloud,但您需要應用程式接受 ID 權杖,或許可以使用這些方法。不過,您應判斷應用程式需要哪些 ID 權杖聲明。

從中繼資料伺服器取得 ID 權杖

當程式碼在可附加服務帳戶的資源上執行時,相關聯服務的中繼資料伺服器通常會提供 ID 權杖。中繼資料伺服器會為附加的服務帳戶產生 ID 權杖。您無法從中繼資料伺服器取得以使用者憑證為依據的 ID 權杖。

在下列 Trusted Cloud 服務上執行程式碼時,您可以從中繼資料伺服器取得 ID 權杖:

如要從中繼資料伺服器擷取 ID 權杖,請查詢服務帳戶的身分端點,如以下範例所示。

curl

AUDIENCE 替換為目標服務的 URI,例如 http://www.example.com

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

PowerShell

AUDIENCE 替換為目標服務的 URI,例如 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

如要執行這個程式碼範例,請先完成下列步驟:


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

執行程式碼範例前,請將 GOOGLE_CLOUD_UNIVERSE_DOMAIN 環境變數設為 s3nsapis.fr

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

如要執行這個程式碼範例,請先完成下列步驟:


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

如要執行這個程式碼範例,請先完成下列步驟:

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

使用連結服務產生 ID 權杖

部分 Trusted Cloud 服務可協助您呼叫其他服務。這些連結服務可能有助於判斷通話時間,或管理包含呼叫服務的工作流程。下列服務在發起對需要 ID 符記的服務的呼叫時,可以自動加入 ID 符記,並為 aud 聲明提供適當的值:

Pub/Sub
Pub/Sub 可讓服務之間進行非同步通訊。 您可以設定 Pub/Sub,在訊息中加入 ID 權杖。詳情請參閱「 推送訂閱的驗證」。

模擬服務帳戶來產生 ID 權杖

服務帳戶模擬功能可讓主體為信任的服務帳戶產生短期憑證。主體隨後可以使用這些憑證,以服務帳戶身分進行驗證。

主體必須具備服務帳戶的 IAM 角色,才能模擬該服務帳戶。如果主體是另一個服務帳戶,直接為該服務帳戶提供必要權限,並允許服務帳戶模擬自身,似乎會比較簡單。這種設定稱為「自我模擬」,會造成安全漏洞,因為服務帳戶可以建立可無限期重新整理的存取權杖。

服務帳戶模擬功能一律涉及兩個主體:代表呼叫者的主體,以及要模擬的服務帳戶 (稱為具備權限的服務帳戶)。

如要模擬服務帳戶來產生 ID 權杖,請按照下列一般程序操作。

如需逐步操作說明,請參閱「建立 ID 權杖」。

  1. 找出或建立服務帳戶,做為具有權限的服務帳戶。

  2. 請參閱產品說明文件,找出叫用目標服務所需的角色。在目標服務中,將這些角色授予服務帳戶。
  3. 找出要執行模擬作業的主體,並設定應用程式預設憑證 (ADC),以便使用這個主體的憑證。

    在開發環境中,主體通常是您使用 gcloud CLI 提供給 ADC 的使用者帳戶。不過,如果您在附加服務帳戶的資源上執行作業,附加的服務帳戶就是主體。

  4. 將服務帳戶 OpenID Connect 身分識別權杖建立者角色 (roles/iam.serviceAccountOpenIdTokenCreator) 授予主體。

  5. 使用 IAM Credentials API 為已授權的服務帳戶產生 ID 權杖。

    更改下列內容:

    • AUDIENCE:目標服務的 URI,例如 http://www.example.com
    • SERVICE_ACCOUNT_EMAIL:具有權限的服務帳戶電子郵件地址。
    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
    

後續步驟