ID 토큰 가져오기

이 페이지에서는 Google 서명 OpenID Connect(OIDC) ID 토큰을 가져오는 몇 가지 방법을 설명합니다. 다음 인증 사용 사례에는 Google 서명 ID 토큰이 필요합니다.

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

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

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

ID 토큰을 가져오는 방법

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

Cloud Run 및 Cloud Functions는 ID 토큰을 가져오는 서비스 특정 방법을 제공합니다. 자세한 내용은 Cloud Run 또는 Cloud Functions에서 호스팅되는 애플리케이션에 인증을 참조하세요.

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

자바

이 코드 샘플을 실행하려면 자바용 Google API 클라이언트 라이브러리를 설치해야 합니다.


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 url = 'http://www.example.com';

const {GoogleAuth} = require('google-auth-library');

async function getIdTokenFromMetadataServer() {
  const googleAuth = new GoogleAuth();
  const client = await googleAuth.getClient();

  // 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.fetchIdToken(url);
  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 토큰을 자동으로 포함할 수 있습니다.

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

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

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

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

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

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

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

  1. 권한 보유 서비스 계정으로 지정할 서비스 계정을 식별 또는 생성합니다. 대상 서비스에서 서비스 계정에 필요한 IAM 역할을 부여합니다.

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

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

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

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

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

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

외부 ID 공급업체를 사용하여 ID 토큰 생성

외부 ID 공급업체를 사용하여 ID 토큰을 생성할 때는 워크로드 아이덴티티 제휴를 사용하여 Google Cloud와 외부 ID 공급업체 사이의 관계를 설정할 수 있습니다. 그런 다음 외부 ID 공급업체에서 제공된 사용자 인증 정보를 사용하여 Google Cloud에서 사용할 수 있는 ID 토큰 또는 액세스 토큰을 생성할 수 있습니다.

외부 ID 공급업체에서 제공된 사용자 인증 정보에 대해 ID 토큰을 생성하려면 다음 단계를 수행합니다.

  1. 대상 서비스를 호출하는 데 필요한 IAM 역할을 제공하도록 서비스 계정을 식별 또는 생성합니다.

    특별히 이 목적을 위해 서비스 계정을 만들고 여기에 필요한 역할만 제공하는 것이 좋습니다. 이 접근 방식은 최소 권한의 원칙을 따릅니다.

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

    • Cloud Run 서비스의 경우 Cloud Run 호출자 역할(roles/run.invoker)을 부여합니다.
    • Cloud Functions의 경우 Cloud Functions 호출자 역할(roles/cloudfunctions.invoker)을 부여합니다.
    • 다른 대상 서비스의 경우 서비스에 대한 제품 문서를 참조하세요.
  3. 워크로드 아이덴티티 제휴 구성에 설명된 대로 ID 공급업체에 대해 워크로드 아이덴티티 제휴를 구성합니다.

  4. 이전 단계에서 설정한 서비스 계정을 가장할 서비스 계정으로 사용하여 외부 ID에 서비스 계정을 가장할 수 있는 권한 부여의 안내를 따릅니다.

  5. REST API를 사용하여 단기 토큰을 획득합니다. 하지만 마지막 단계에서는 대신 generateIdToken 메서드를 사용하여 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
    

    다음을 바꿉니다.

    • SERVICE_ACCOUNT_EMAIL: 서비스 계정의 이메일 주소입니다.
    • AUDIENCE: 토큰이 액세스하는 데 사용될 애플리케이션 또는 서비스와 같은 토큰의 사용 대상입니다.

다음 단계