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

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

אסימון בחתימת Google נדרש בתרחישי האימות הבאים:

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

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

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

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

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

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

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

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

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

כדי לאחזר אסימון מזהה משרת המטא-נתונים, צריך להריץ שאילתה על נקודת הקצה (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

כדי להריץ את דוגמת הקוד הזו, צריך להתקין את ספריית הלקוח של Auth ל-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

כדי להריץ את דוגמת הקוד הזו, צריך להתקין את ספריית Google Auth ל-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

כדי להריץ את דוגמת הקוד הזו, צריך להתקין את ספריית Python ל-Google Auth.


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

כדי להריץ את דוגמת הקוד הזו, צריך להתקין את ספריית Google Auth ל-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

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

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

Cloud Scheduler
‫Cloud Scheduler הוא מתזמן משימות cron מנוהל באופן מלא ברמת הארגון. בהגדרות של Cloud Scheduler ניתן לכלול אסימון מזהה או אסימון גישה שיצורפו להפעלה של שירותים אחרים. למידע נוסף, ראו שימוש באימות עם HTTP Target.
Cloud Tasks
באמצעות שירות Cloud Tasks תוכלו לנהל את הביצוע של משימות מבוזרות. בהגדרות של משימה ניתן לכלול אסימון מזהה או אסימון גישה שיצורפו לקריאה לשירות. למידע נוסף, ראו שימוש במשימות של HTTP Target עם אסימוני אימות.
Pub/Sub
באמצעות שירות Pub/Sub ניתן לקיים תקשורת אסינכרונית בין שירותים. בהגדרות של Pub/Sub ניתן לכלול אסימון מזהה עם הודעה. למידע נוסף, ראו אימות למינוי דחיפה.
Workflows
‫Workflows היא פלטפורמת תזמור מנוהלת במלואה שמבצעת שירותים בסדר שאתם מגדירים: תהליך עבודה. אפשר להגדיר תהליך עבודה שיכלול אסימון מזהה או אסימון גישה כשהוא מפעיל שירות אחר. מידע נוסף זמין במאמר בנושא שליחת בקשות מאומתות מתהליך עבודה.

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

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

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

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

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

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

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

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

    • ל שירותים של Cloud Run, מקצים את התפקיד Cloud Run Invoker‏ (roles/run.invoker).
    • לפונקציות Cloud Run, מקצים את התפקיד Cloud Functions Invoker‏ (roles/cloudfunctions.invoker).
    • למידע על שירותי יעד אחרים, אפשר לעיין במסמכי התיעוד של המוצר לכל שירות.
  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
    

יצירת אסימון מזהה גנרי לפיתוח באמצעות Cloud Run ופונקציות Cloud Run

תוכלו להשתמש ב-CLI של gcloud כדי לקבל אסימון מזהה לפרטי הכניסה של המשתמש שלכם. אפשר להשתמש באסימון המזהה הזה בכל השירותים של Cloud Run והפונקציות של Cloud Run שיש למשתמש את הרשאות IAM הדרושות כדי להפעיל אותם. האסימון הזה לא יפעל לשום אפליקציה אחרת.

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