קבלת אסימון מזהה

בדף הזה נתאר כמה דרכים לקבלת אסימון מזהה של OpenID Connect ‏(OIDC) בחתימת Google.

בקטע אסימונים מזהים מוסבר על התוכן ועל משך החיים של אסימונים.

אפשר להשתמש באסימונים מזהים רק באפליקציה או בשירות הספציפיים שמצוינים בהצהרת aud שלהם. במאמר הזה נשתמש במונח שירות היעד כדי להתייחס לאפליקציה או לשירות שבהם אפשר להשתמש באסימון המזהה לצורך אימות.

אחרי שמקבלים את האסימון המזהה, אפשר לכלול אותו בכותרת Authorization של בקשה ששולחים לשירות היעד.

שיטות לקבלת אסימון מזהה

יש כמה דרכים לקבל אסימון מזהה, ובדף זה נתאר את השיטות הבאות:

סביר להניח שתוכלו להשתמש בשיטות האלה גם עם אפליקציות שאינן מתארחות ב-Cloud de Confiance. עם זאת, עליכם לבדוק אילו הצהרות נדרשות באסימון המזהה עבור כל אפליקציה.

קבלת אסימון מזהה משרת המטא-נתונים

כשהקוד שלכם פועל במשאב שאפשר לצרף לו חשבון שירות, בדרך כלל אפשר לקבל את האסימון המזהה משרת המטא-נתונים של השירות המצורף. האסימונים המזהים נוצרים על ידי שרת המטא-נתונים עבור חשבון השירות המצורף. לא ניתן לקבל משרת המטא-נתונים אסימון מזהה שמבוסס על פרטי הכניסה של משתמשים.

כשאתם מפעילים את הקוד שלכם בשירותים הבאים, תוכלו לקבל אסימון מזהה משרת המטא-נתונים: Cloud de Confiance

כדי לאחזר אסימון מזהה משרת המטא-נתונים, צריך להריץ שאילתה על נקודת הקצה (endpoint) של חשבון השירות כפי שמתואר בדוגמה הבאה.

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

כדי להריץ את דוגמת הקוד הזו, צריך קודם לבצע את השלבים הבאים:

  • מתקינים את Google Auth Python Library.
  • מגדירים את משתנה הסביבה GOOGLE_CLOUD_UNIVERSE_DOMAIN לערך s3nsapis.fr.


import google
from google.auth import compute_engine
import google.auth.transport.requests
import google.oauth2.credentials


def idtoken_from_metadata_server(url: str) -> None:
    """
    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

יצירת אסימון מזהה באמצעות שירות מחבר

בשירותים מסוימים Cloud de Confiance אפשר לקרוא לשירותים אחרים. השירותים המחברים האלה מאפשרים לקבוע מתי תתבצע הקריאה ולנהל תהליך עבודה שכולל קריאה לשירות. בשירותים הבאים ניתן לכלול אסימון מזהה באופן אוטומטי, עם הערך המתאים להצהרה aud, בכל קריאה יזומה לשירות שבו נדרש אסימון מזהה:

Pub/Sub
באמצעות שירות Pub/Sub ניתן לקיים תקשורת אסינכרונית בין שירותים. בהגדרות של Pub/Sub ניתן לכלול אסימון מזהה עם הודעה. למידע נוסף, ראו אימות למינוי דחיפה.

יצירת אסימון מזהה על ידי התחזות לחשבון שירות

אפשר ליצור פרטי כניסה לטווח קצר של חשבון שירות מהימן עבור חשבון משתמש, על ידי התחזות לחשבון שירות. אפשר להשתמש בפרטי הכניסה האלה כדי לאמת את חשבון המשתמש בתור חשבון השירות.

כדי לאפשר לחשבון המשתמש להתחזות לחשבון שירות, צריך להיות לו תפקיד IAM שמאפשר התחזות באותו חשבון שירות. אם חשבון המשתמש הוא גם חשבון שירות בעצמו, יכול להיות שייראה קל יותר לספק את ההרשאות הנדרשות ישירות לחשבון השירות הזה ולאפשר לו להתחזות לעצמו. אבל הגדרה כזו, שנקראת 'התחזות עצמית', יוצרת נקודת חולשה באבטחה כי היא מאפשרת לחשבון השירות ליצור אסימון גישה שניתן לרענן לצמיתות.

התחזות לחשבון שירות תמיד צריכה לכלול שני חשבונות משתמשים: חשבון משתמש שמייצג את הקריאה לשירות, וחשבון השירות שאליו הוא מתחזה, שנקרא גם חשבון השירות הנושא את ההרשאות.

כדי ליצור אסימון מזהה באמצעות התחזות לחשבון שירות, פועלים לפי התהליך הכללי הבא.

להוראות מפורטות, תוכלו לקרוא את המאמר יצירת אסימון מזהה.

  1. מאתרים או יוצרים חשבון שירות שישמש כחשבון השירות הנושא את ההרשאות.

  2. כדי לזהות את התפקידים הנדרשים להפעלת שירות היעד, אפשר לעיין במסמכי התיעוד של המוצר. מקצים לחשבון השירות את התפקידים הבאים בשירות היעד:
  3. מאתרים את חשבון המשתמש שבו תתבצע ההתחזות, ומגדירים לו את פרטי הכניסה לשימוש ב-Application Default Credentials‏ (ADC).

    בסביבות פיתוח, חשבון המשתמש הוא בדרך כלל החשבון שסיפקתם ל-ADC באמצעות ה-CLI של gcloud. עם זאת, אם אתם משתמשים במשאב עם חשבון שירות מצורף, חשבון השירות המצורף ישמש בתור חשבון המשתמש.

  4. מקצים לחשבון המשתמש את התפקיד 'יצירת אסימון זהות של OpenID Connect בחשבון השירות' (roles/iam.serviceAccountOpenIdTokenCreator).

  5. משתמשים ב-IAM Credentials API כדי ליצור את האסימון המזהה לחשבון השירות עם ההרשאות.

    מחליפים את מה שכתוב בשדות הבאים:

    • 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
    

המאמרים הבאים