使用客户端库时进行身份验证

本页面介绍了如何使用客户端库和应用默认凭据访问 Google API。

通过客户端库,您可以更轻松地使用支持的语言访问 Google Cloud API。您可以直接通过向服务器发出原始请求来使用 Google Cloud API,但客户端库可提供简化,从而显著减少您需要编写的代码量。这对于身份验证尤其如此,因为客户端库支持应用默认凭据 (ADC)

如果您想使用 API 密钥,则无需使用 ADC。如需了解详情,请参阅将 API 密钥与客户端库搭配使用

将应用默认凭据与客户端库搭配使用

如需使用应用默认凭据对应用进行身份验证,您必须先为应用运行的环境设置 ADC。使用客户端库创建客户端时,客户端库会自动检查和使用您提供给 ADC 的凭据,从而向代码使用的 API 进行身份验证。您的应用无需明确对令牌进行身份验证或管理;这些要求由身份验证库自动管理。

对于本地开发环境,您可以使用 gcloud CLI 通过用户凭据服务账号模拟来设置 ADC。对于生产环境,您可以通过关联服务账号来设置 ADC。

示例客户端创建

以下代码示例为 Cloud Storage 服务创建客户端。您的代码可能需要不同的客户端;这些示例仅用于展示如何在无需任何代码来明确进行身份验证的情况下创建客户端并使用它。

您必须先完成以下步骤,然后才能运行后续示例:

Go

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/storage"
	"google.golang.org/api/iterator"
)

// authenticateImplicitWithAdc uses Application Default Credentials
// to automatically find credentials and authenticate.
func authenticateImplicitWithAdc(w io.Writer, projectId string) error {
	// projectId := "your_project_id"

	ctx := context.Background()

	// NOTE: Replace the client created below with the client required for your application.
	// Note that the credentials are not specified when constructing the client.
	// The client library finds your credentials using ADC.
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	it := client.Buckets(ctx, projectId)
	for {
		bucketAttrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintf(w, "Bucket: %v\n", bucketAttrs.Name)
	}

	fmt.Fprintf(w, "Listed all storage buckets.\n")

	return nil
}

Java


import com.google.api.gax.paging.Page;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.IOException;

public class AuthenticateImplicitWithAdc {

  public static void main(String[] args) throws IOException {
    // TODO(Developer):
    //  1. Before running this sample,
    //  set up Application Default Credentials as described in
    //  https://cloud.google.com/docs/authentication/external/set-up-adc
    //  2. Replace the project variable below.
    //  3. Make sure you have the necessary permission to list storage buckets
    //  "storage.buckets.list"
    String projectId = "your-google-cloud-project-id";
    authenticateImplicitWithAdc(projectId);
  }

  // When interacting with Google Cloud Client libraries, the library can auto-detect the
  // credentials to use.
  public static void authenticateImplicitWithAdc(String project) throws IOException {

    // *NOTE*: Replace the client created below with the client required for your application.
    // Note that the credentials are not specified when constructing the client.
    // Hence, the client library will look for credentials using ADC.
    //
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    Storage storage = StorageOptions.newBuilder().setProjectId(project).build().getService();

    System.out.println("Buckets:");
    Page<Bucket> buckets = storage.list();
    for (Bucket bucket : buckets.iterateAll()) {
      System.out.println(bucket.toString());
    }
    System.out.println("Listed all storage buckets.");
  }
}

Node.js

/**
 * TODO(developer):
 *  1. Uncomment and replace these variables before running the sample.
 *  2. Set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc
 *  3. Make sure you have the necessary permission to list storage buckets "storage.buckets.list"
 *    (https://cloud.google.com/storage/docs/access-control/iam-permissions#bucket_permissions)
 */
// const projectId = 'YOUR_PROJECT_ID';

const {Storage} = require('@google-cloud/storage');

async function authenticateImplicitWithAdc() {
  // This snippet demonstrates how to list buckets.
  // NOTE: Replace the client created below with the client required for your application.
  // Note that the credentials are not specified when constructing the client.
  // The client library finds your credentials using ADC.
  const storage = new Storage({
    projectId,
  });
  const [buckets] = await storage.getBuckets();
  console.log('Buckets:');

  for (const bucket of buckets) {
    console.log(`- ${bucket.name}`);
  }

  console.log('Listed all storage buckets.');
}

authenticateImplicitWithAdc();

PHP

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

/**
 * Authenticate to a cloud client library using a service account implicitly.
 *
 * @param string $projectId The Google project ID.
 */
function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python


from google.cloud import storage


def authenticate_implicit_with_adc(project_id="your-google-cloud-project-id"):
    """
    When interacting with Google Cloud Client libraries, the library can auto-detect the
    credentials to use.

    // TODO(Developer):
    //  1. Before running this sample,
    //  set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc
    //  2. Replace the project variable.
    //  3. Make sure that the user account or service account that you are using
    //  has the required permissions. For this sample, you must have "storage.buckets.list".
    Args:
        project_id: The project id of your Google Cloud project.
    """

    # This snippet demonstrates how to list buckets.
    # *NOTE*: Replace the client created below with the client required for your application.
    # Note that the credentials are not specified when constructing the client.
    # Hence, the client library will look for credentials using ADC.
    storage_client = storage.Client(project=project_id)
    buckets = storage_client.list_buckets()
    print("Buckets:")
    for bucket in buckets:
        print(bucket.name)
    print("Listed all storage buckets.")

Ruby

def authenticate_implicit_with_adc project_id:
  # The ID of your Google Cloud project
  # project_id = "your-google-cloud-project-id"

  ###
  # When interacting with Google Cloud Client libraries, the library can auto-detect the
  # credentials to use.
  # TODO(Developer):
  #   1. Before running this sample,
  #      set up ADC as described in https://cloud.google.com/docs/authentication/external/set-up-adc
  #   2. Replace the project variable.
  #   3. Make sure that the user account or service account that you are using
  #      has the required permissions. For this sample, you must have "storage.buckets.list".
  ###

  require "google/cloud/storage"

  # This sample demonstrates how to list buckets.
  # *NOTE*: Replace the client created below with the client required for your application.
  # Note that the credentials are not specified when constructing the client.
  # Hence, the client library will look for credentials using ADC.
  storage = Google::Cloud::Storage.new project_id: project_id
  buckets = storage.buckets
  puts "Buckets: "
  buckets.each do |bucket|
    puts bucket.name
  end
  puts "Plaintext: Listed all storage buckets."
end

使用外部来源的凭据配置时的安全要求

通常,您可以使用 gcloud CLI 命令或 Google Cloud 控制台生成凭据配置。例如,您可以使用 gcloud CLI 生成本地 ADC 文件或登录配置文件。同样,您可以使用 Google Cloud 控制台创建和下载服务账号密钥。

不过,在某些用例中,凭据配置是由外部实体提供给您的;这些凭据配置旨在用于向 Google API 进行身份验证。

某些类型的凭据配置包含端点和文件路径,身份验证库会使用这些端点和文件路径来获取令牌。接受来自外部来源的凭据配置时,您必须先验证配置,然后才能使用该配置。如果您不验证配置,恶意攻击者可能会使用凭据破坏您的系统和数据。

验证来自外部来源的凭据配置

您需要如何验证外部凭据取决于您的应用接受哪些类型的凭据。

验证服务账号密钥

如果您的应用接受服务账号密钥,请使用专门针对服务账号密钥的凭据加载器,如以下示例所示。类型专用凭据加载器仅解析服务账号密钥中存在的字段,这些字段不会泄露任何漏洞。

C#

var saCredential = ServiceAccountCredential.FromServiceAccountData(stream);

C++

auto cred = google::cloud::MakeServiceAccountCredentials(json)

Java

ServiceAccountCredentials credentials =
      ServiceAccountCredentials.fromJson(json, new HttpTransportFactory());

Node.js

const keys = JSON.parse(json_input)
const authClient = JWT.fromJSON(keys);

PHP

cred = new Google\Auth\Credentials\ServiceAccountCredentials($scope, $jsonKey);

Python

cred = service_account.Credentials.from_service_account_info(json_data)

Ruby

creds = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: json_stream)

如果您无法使用特定于类型的凭据加载器,请通过确认 type 字段的值为 service_account 来验证凭据。如果 type 字段的值是任何其他值,请勿使用服务账号密钥。

验证其他凭据配置

如果您的应用除了服务账号密钥之外还接受任何类型的凭据,则必须执行额外的验证。其他类型的凭据配置示例包括 ADC 凭据文件工作负载身份联合凭据文件Workforce Identity Federation 登录配置文件

下表列出了您需要验证的字段(如果您的凭据中包含这些字段)。并非所有凭据配置都包含所有这些字段。

字段 用途 预期值
service_account_impersonation_url 身份验证库使用此字段访问端点,以便为要被冒充的服务账号生成访问令牌。 https://iamcredentials.googleapis.com.com/v1/projects/-/serviceAccounts/service account email:generateAccessToken
token_url 身份验证库会向此端点发送外部令牌,以将其交换为联合访问令牌 https://sts.googleapis.com.com/v1/token
credential_source.file 身份验证库会从此字段指定的位置读取文件中的外部令牌,并将其发送到 token_url 端点。 包含外部令牌的文件的路径。您应该能认出此路径。
credential_source.url 用于返回外部令牌的端点。身份验证库会向此网址发送请求,并将响应发送到 token_url 端点。

以下任一项:

  • 您的云服务提供商提供的知名端点。
  • 您明确设置为提供令牌的端点。
credential_source.executable.command 如果 GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES 环境变量设置为 1,身份验证库会运行此命令或可执行文件。 用于返回外部令牌的可执行文件或命令。 您应该认识到此命令并验证其安全性。
credential_source.aws.url 身份验证库会向此网址发出请求,以检索 AWS 安全令牌。

以下任一确切值:

  • http://169.254.169.254/latest/meta-data/iam/security-credentials
  • http://[fd00:ec2::254]/latest/meta-data/iam/security-credentials
credential_source.aws.region_url 身份验证库会向此网址发出请求,以检索有效的 AWS 区域。

以下任一确切值:

  • http://169.254.169.254/latest/meta-data/placement/availability-zone
  • http://[fd00:ec2::254]/latest/meta-data/placement/availability-zone
credential_source.aws.imdsv2_session_token_url 身份验证库会向此网址发出请求,以检索 AWS 会话令牌。

以下任一确切值:

  • http://169.254.169.254/latest/api/token
  • http://[fd00:ec2::254]/latest/api/token

后续步骤