ID 토큰 가져오기

이 페이지에서는 Google 서명 OpenID Connect(OIDC) ID 토큰을 가져오는 몇 가지 방법을 설명합니다.

다음 인증 사용 사례에는 Google 서명 ID 토큰이 필요합니다.

ID 토큰 콘텐츠 및 수명에 대한 자세한 내용은 ID 토큰을 참조하세요.

ID 토큰에는 aud 클레임의 값으로 지정되어 사용할 수 있는 특정 서비스 또는 애플리케이션이 포함되어 있습니다. 이 페이지에서는 대상 서비스라는 용어를 사용하여 ID 토큰을 사용하여 인증할 수 있는 서비스 또는 애플리케이션을 지칭합니다.

ID 토큰을 받으면 대상 서비스에 대한 요청의 Authorization 헤더에 포함할 수 있습니다.

ID 토큰을 가져오는 방법

다양한 방법으로 ID 토큰을 가져올 수 있습니다. 이 페이지에서는 다음 방법을 설명합니다.

Google Cloud에서 호스팅되지 않는 애플리케이션에서 ID 토큰을 수락해야 하는 경우 이러한 방법을 사용할 수 있지만 애플리케이션에 필요한 ID 토큰 클레임을 확인해야 합니다.

메타데이터 서버에서 ID 토큰 가져오기

코드가 서비스 계정을 연결할 수 있는 리소스에서 실행되는 경우에는 연결된 서비스의 메타데이터 서버가 일반적으로 ID 토큰을 제공할 수 있습니다. 메타데이터 서버는 연결된 서비스 계정에 대한 ID 토큰을 생성합니다. 메타데이터 서버의 사용자 인증 정보를 기반으로 ID 토큰을 가져올 수 없습니다.

코드가 다음 Google Cloud 서비스에서 실행될 때 메타데이터 서버에서 ID 토큰을 가져올 수 있습니다.

메타데이터 서버에서 ID 토큰을 검색하려면 이 예시에 표시된 것처럼 서비스 계정에 대해 ID 엔드포인트를 쿼리합니다.

curl

AUDIENCEhttp://www.example.com과 같은 대상 서비스의 URI로 바꿉니다.

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

PowerShell

AUDIENCEhttp://www.example.com과 같은 대상 서비스의 URI로 바꿉니다.

$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

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

이 코드 샘플을 실행하려면 Node.js용 Google 인증 라이브러리'를 설치해야 합니다.

/**
 * 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

이 코드 샘플을 실행하려면 Google 인증 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

이 코드 샘플을 실행하려면 Ruby용 Google 인증 라이브러리를 설치해야 합니다.

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 토큰 생성

일부 Google Cloud 서비스는 다른 서비스를 호출하는 데 도움이 됩니다. 이러한 연결 서비스는 호출이 수행되는 시점을 확인하거나 서비스 호출이 포함된 워크플로를 관리하는 데 도움이 될 수 있습니다. 다음 서비스는 ID 토큰이 필요한 서비스에 대한 호출을 시작할 때 aud 클레임에 적절한 값이 있는 ID 토큰을 자동으로 포함할 수 있습니다.

Cloud Scheduler
Cloud Scheduler는 엔터프라이즈 수준의 완전 관리형 크론 작업 스케줄러로서 다른 서비스를 호출할 때 ID 토큰이나 액세스 토큰을 포함하도록 Cloud Scheduler를 구성할 수 있습니다. 자세한 내용은 HTTP 대상에 인증 사용을 참조하세요.
Cloud Tasks
Cloud Task를 사용하여 분산된 태스크 수행을 관리할 수 있습니다. 서비스를 호출할 때 ID 토큰 또는 액세스 토큰을 포함하도록 태스크를 구성할 수 있습니다. 자세한 내용은 인증 토큰과 함께 HTTP 대상 태스크 사용을 참조하세요.
Pub/Sub
Pub/Sub는 서비스 간의 비동기 통신을 사용 설정합니다. 메시지에 ID 토큰을 포함하도록 Pub/Sub를 구성할 수 있습니다. 자세한 내용은 푸시 구독 인증을 참조하세요.
워크플로
Workflows는 워크플로라는 정의된 순서로 서비스를 실행하는 완전 관리형 조정 플랫폼입니다. 다른 서비스를 호출할 때 ID 토큰 또는 액세스 토큰을 포함하도록 워크플로를 정의할 수 있습니다. 자세한 내용은 워크플로에서 인증된 요청 수행을 참조하세요.

서비스 계정을 가장하여 ID 토큰 생성

서비스 계정 가장을 통해 주 구성원이 신뢰할 수 있는 서비스 계정에 대해 단기 사용자 인증 정보를 생성할 수 있습니다. 그런 다음 주 구성원이 이러한 사용자 인증 정보를 사용하여 서비스 계정으로 인증할 수 있습니다.

주 구성원이 서비스 계정을 가장하려면 서비스 계정에 가장을 사용 설정하는 IAM 역할이 있어야 합니다. 주 구성원이 자체적으로 다른 서비스 계정인 경우 필요한 권한을 해당 서비스 계정에 직접 제공하여 자체를 가장하도록 사용 설정하는 것이 더 쉬워 보일 수 있습니다. 자체 가장이라고 부르는 이러한 구성에는 서비스 계정이 영구적으로 새로고침될 수 있는 액세스 토큰을 만들 수 있어서 보안 취약점이 있습니다.

서비스 계정 가장에는 항상 2개의 주 구성원이 포함됩니다. 하나는 호출자를 나타내는 주 구성원이고 다른 하나는 권한 보유 서비스 계정이라고 부르는 가장되는 대상 서비스 계정입니다.

서비스 계정을 가장하여 ID 토큰을 생성하려면 다음과 같은 일반적인 프로세스를 사용합니다.

단계별 안내는 ID 토큰 만들기를 참조하세요.

  1. 권한 보유 서비스 계정으로 지정할 서비스 계정을 식별 또는 생성합니다.

  2. 대상 서비스를 호출하는 데 필요한 역할을 식별합니다. 이러한 역할을 대상 서비스의 서비스 계정에 부여합니다.

    • Cloud Run 서비스의 경우 Cloud Run 호출자 역할(roles/run.invoker)을 부여합니다.
    • Cloud Functions의 경우 Cloud Functions 호출자 역할(roles/cloudfunctions.invoker)을 부여합니다.
    • 다른 대상 서비스의 경우 서비스에 대한 제품 문서를 참조하세요.
  3. 가장을 수행하는 주 구성원을 식별하고 이 주 구성원에 대해 사용자 인증 정보를 사용하도록 애플리케이션 기본 사용자 인증 정보(ADC)를 설정합니다.

    개발 환경에서 주 구성원은 일반적으로 gcloud CLI를 사용하여 ADC에 제공한 사용자 계정입니다. 그러나 서비스 계정이 연결된 리소스에서 실행하는 경우에는 연결된 서비스 계정이 주 구성원입니다.

  4. 주 구성원에게 서비스 계정 OpenID Connect ID 토큰 생성자 역할(roles/iam.serviceAccountOpenIdTokenCreator)을 부여합니다.

  5. IAM Credentials API를 사용하여 승인된 서비스 계정에 대해 ID 토큰을 생성합니다.

Cloud Run 및 Cloud Functions로 개발할 수 있는 일반 ID 토큰 생성

gcloud CLI를 사용하여 호출자가 호출하는 데 필요한 IAM 권한이 있는 모든 Cloud Run 서비스 또는 Cloud 함수에서 사용할 수 있는 사용자 인증 정보의 ID 토큰을 가져올 수 있습니다. 이 토큰은 다른 애플리케이션에서 작동하지 않습니다.

다음 단계