Google Auth Library 是適用於 Java 的開放原始碼驗證用戶端程式庫。 本文說明如何使用這個程式庫,驗證 Java 應用程式以存取 Google Cloud 服務。
本指南將說明如何:
- 使用 Maven、Gradle 或 Simple Build Tool (SBT),將必要的 Auth 程式庫依附元件新增至專案。
- 使用各種方法進行驗證,重點在於應用程式預設憑證 (ADC)。
- 設定進階驗證情境,包括 Workload Identity 聯盟、員工身分聯盟和服務帳戶模擬。
- 產生及使用範圍縮減的權杖,限制權限。
- 將憑證與 Google HTTP 用戶端程式庫整合。
本說明文件適用於 Java 開發人員。如需完整的 API 詳細資料,請參閱「Google Auth Library API 說明文件」。
Java 專用的 Google Auth 程式庫包含四個構件:
google-auth-library-credentials包含 Google 憑證的基本類別和介面。google-auth-library-appengine包含 App Engine 憑證,且依附於 App Engine SDK。google-auth-library-oauth2-http包含各種憑證和公用程式方法,包括取得應用程式預設憑證的功能。此外,這項服務也提供伺服器端方法,用於產生範圍縮減的權杖。google-auth-library-cab-token-generator提供產生範圍縮減權杖的用戶端方法。
驗證憑證設定
如果您使用來自外部來源的憑證設定 (例如 JSON、檔案路徑或串流),請務必驗證這些設定。向 Google API 或用戶端程式庫提供未經驗證的憑證,以進行驗證Google Cloud 可能會導致系統和資料安全受到威脅。
詳情請參閱「外部來源憑證」一節。預設憑證。
匯入驗證程式庫
如要匯入 Auth 程式庫,請使用 com.google.cloud:libraries-bom,或透過 Maven 或 Gradle 使用 Google Auth 程式庫物料清單。
Java SDK 程式庫 - bom
如要使用 Auth 程式庫,在 Java SDK (例如 google-cloud-datastore) 中向用戶端程式庫進行驗證,請使用 libraries-bom,這會提取與該用戶端程式庫相容的 Auth 程式庫版本。
舉例來說,如要使用 pom.xml 透過 Maven 匯入 Auth 程式庫,請執行下列操作:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.53.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
如果您未使用 libraries-bom 或其他用戶端程式庫,請直接透過 Google Auth Library Bill of Materials 匯入 Auth 模組。
Google Auth Library 物料清單
您可以使用 Google Auth Library 物料清單,確保驗證模組和相關的遞移依附元件相容。
Maven
請將以下內容新增到您的 pom.xml 檔案中:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-bom</artifactId>
<version>1.30.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在 <dependencies> 區段中,您可以指定所需的任何 Auth 模組。舉例來說,如要加入 google-auth-library-oauth2-http 模組,請新增下列 <dependency> 項目:
<dependency>
<groupId>com.google.auth</groupId>
<!-- Let the BOM manage the module and dependency versions -->
<!-- Replace with the module(s) that are needed -->
<artifactId>google-auth-library-oauth2-http</artifactId>
</dependency>
視應用程式需求而定,將範例中的 google-auth-library-oauth2-http 替換為 google-auth-library-credentials 或 google-auth-library-appengine。
Gradle
與 Maven 類似,Gradle 使用者可以透過 google-auth-library-bom 管理依附元件版本,並確保不同 google-auth-library 模組之間的相容性。
如要搭配 Gradle 使用 BOM,請將 BOM 新增為 platform 依附元件。然後新增所需的 google-auth-library 模組。BOM 可確保您使用的所有模組版本都相容。舉例來說,請將以下內容新增到 build.gradle 檔案中:
dependencies {
// The BOM will manage the module versions and transitive dependencies
implementation platform('com.google.auth:google-auth-library-bom:1.30.1')
// Replace with the module(s) that are needed
implementation 'com.google.auth:google-auth-library-oauth2-http'
}
Scala
與 Maven 和 Gradle 不同,SBT (Scala 建構工具) 不支援 Maven 物料清單 (BOM)。因此,使用 Scala 時,您無法匯入 google-auth-library-bom,自動處理 Auth Library 模組的相容版本及其遞移依附元件。
您必須直接將每個必要子模組新增至 build.sbt 檔案。請務必明確指定並對齊所用所有 google-auth-library 模組的版本。如果版本不一致,可能會導致遞移依附元件之間發生版本衝突,進而造成應用程式出現非預期的行為或執行階段錯誤。
如果您使用 SBT,請在依附元件中加入以下指令:
// Replace this with the implementation module that suits your needs
libraryDependencies += "com.google.auth" % "google-auth-library-oauth2-http" % "1.30.1"
從 GoogleCredential 遷移至 GoogleCredentials
GoogleCredential
已淘汰,建議改用 GoogleCredentials。google-api-java-client
使用應用程式預設憑證 (ADC) 例項化 GoogleCredentials。建議做法如下:
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
GoogleCredentials 的使用方式取決於用戶端程式庫:
Cloud 用戶端程式庫: 這些程式庫會自動使用應用程式預設憑證 (ADC),因此您不需要在程式碼中提供憑證。
Google API 用戶端程式庫: 您必須例項化
GoogleCredentials,並將其傳遞至用戶端。如需範例,請參閱 Google API Java 用戶端指南。
應用程式預設憑證
Google Auth Library 提供 Java 適用的應用程式預設憑證 (ADC) 實作項目。ADC 提供取得授權憑證的方法,可呼叫 Google API。
如果應用程式需要獨立於使用者的身分和授權層級,請使用 ADC。我們建議使用 ADC 授權對 Cloud API 發出的呼叫,特別是在 Google Cloud上建構應用程式時。
ADC 也支援工作負載身分聯盟,可讓應用程式從外部平台 (例如 Amazon Web Services (AWS)、Microsoft Azure,或任何支援 OpenID Connect (OIDC) 的身分提供者) 存取 Google Cloud 資源。對於非Google Cloud 環境,建議使用工作負載身分聯盟,因為這樣就不必在本機下載、管理及儲存服務帳戶私密金鑰。
取得應用程式預設憑證
如要取得應用程式預設憑證,請使用 GoogleCredentials.getApplicationDefault() 或 GoogleCredentials.getApplicationDefault(HttpTransportFactory)。這些方法會傳回應用程式預設憑證,以識別及授權整個應用程式。
系統會依下列順序搜尋應用程式預設憑證:
GOOGLE_APPLICATION_CREDENTIALS環境變數指向的憑證檔案。- Google Cloud SDK
gcloud auth application-default login指令提供的憑證。 - Google App Engine 內建憑證。
- Google Cloud Shell 內建憑證。
- Google Compute Engine 內建憑證。
- 如要略過這項檢查,請設定環境變數
NO_GCE_CHECK=true。 - 設定
GCE_METADATA_HOST=<hostname>環境變數,自訂中繼資料伺服器位址。
- 如要略過這項檢查,請設定環境變數
明確載入憑證
如要從服務帳戶 JSON 金鑰取得憑證,請使用 GoogleCredentials.fromStream(InputStream) 或 GoogleCredentials.fromStream(InputStream, HttpTransportFactory),如下列程式碼範例所示。
存取權杖可用之前,必須先重新整理憑證。
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("/path/to/credentials.json"));
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
// OR
AccessToken token = credentials.refreshAccessToken();
模擬憑證
使用 ImpersonatedCredentials 允許憑證 (主體) 模擬服務帳戶 (目標)。這樣一來,主體就能以目標身分存取資源,不必使用目標的私密金鑰。
如要使用 ImpersonatedCredentials,必須符合下列條件:
- 主體的專案必須啟用
IAMCredentialsAPI。 - 主體必須在目標服務帳戶中擁有
Service Account Token Creator(身分與存取權管理) 角色。
下列程式碼範例會建立 ImpersonatedCredentials。主體的憑證是從應用程式預設憑證 (ADC) 取得。產生的ImpersonatedCredentials隨後會用來以目標服務帳戶的身分存取 Google Cloud Storage。
// The principal (ADC) has the Service Account Token Creator role on the target service account.
GoogleCredentials sourceCredentials =
GoogleCredentials.getApplicationDefault()
.createScoped(Arrays.asList("https://www.googleapis.com/auth/iam"));
ImpersonatedCredentials credentials =
ImpersonatedCredentials.newBuilder()
.setSourceCredentials(sourceCredentials)
.setTargetPrincipal(
"impersonated-account@project.iam.gserviceaccount.com")
.setScopes(Arrays.asList("https://www.googleapis.com/auth/devstorage.read_only"))
.build();
Storage storage =
StorageOptions.newBuilder().setProjectId("project-id").setCredentials(credentials).build()
.getService();
for (Bucket b : storage.list().iterateAll()) {
System.out.println(b);
}
Workload Identity 聯盟
透過 Workload Identity Federation,應用程式可以存取 Amazon Web Services (AWS)、Microsoft Azure 的資源,或任何支援 OpenID Connect (OIDC) 的身分識別提供者。 Google Cloud
傳統上,在外部執行的應用程式會使用服務帳戶金鑰存取資源。 Google Cloud Google Cloud 使用身分聯盟,工作負載可以模擬服務帳戶。這項功能可讓外部工作負載直接存取 Google Cloud 資源,免除與服務帳戶金鑰相關的維護和安全負擔。
從 AWS 存取資源
如要存取 Amazon Web Services (AWS) 的資源,請先設定 Workload Identity 聯盟。 Google Cloud 如需詳細設定程序,請參閱「從 AWS 存取資源」。
您將在該程序中產生憑證設定檔。 這個檔案包含非機密中繼資料,可指示程式庫如何擷取外部主體權杖,並換取服務帳戶存取權杖。您可以使用 Google Cloud CLI 產生檔案:
# Generate an AWS configuration file.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>AWS_PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--aws \
--output-file /path/to/generated/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。AWS_PROVIDER_ID:AWS 供應商 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。
這個範例會在指定的輸出檔案中產生設定檔。
如果您使用 AWS IMDSv2,則需要在 gcloud iam workload-identity-pools create-cred-config 指令中新增 --enable-imdsv2 旗標:
gcloud iam workload-identity-pools create-cred-config \
projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/AWS_PROVIDER_ID \
--service-account SERVICE_ACCOUNT_EMAIL \
--aws \
--output-file /path/to/generated/config.json \
--enable-imdsv2
您現在可以使用 Auth 程式庫,從 AWS 呼叫 Google Cloud 資源。
從 Microsoft Azure 存取資源
如要存取 Microsoft Azure 的資源,您必須先設定工作負載身分聯盟。 Google Cloud 如需詳細設定程序,請參閱「從 Azure 存取資源」。
您將在該程序中產生憑證設定檔。 這個檔案包含非機密中繼資料,可指示程式庫如何擷取外部主體權杖,並換取服務帳戶存取權杖。您可以使用 Google Cloud CLI 產生檔案:
# Generate an Azure configuration file.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>AZURE_PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--azure \
--output-file /path/to/generated/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。AZURE_PROVIDER_ID: Azure 供應商 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。
這個指令會在指定的輸出檔案中產生設定檔。
您現在可以使用 Auth 程式庫,從 Azure 呼叫 Google Cloud 資源。
從 OIDC 識別資訊提供者存取資源
如要從支援 OpenID Connect (OIDC) 的識別資訊提供者存取 Google Cloud 資源,您必須先設定工作負載身分聯盟,詳情請參閱「從 OIDC 識別資訊提供者設定工作負載身分聯盟」。
在該程序中,您將使用 Google Cloud CLI 產生憑證設定檔。這個檔案包含非機密中繼資料,可指示程式庫如何擷取外部主體權杖,並換取服務帳戶存取權杖。
對於 OIDC 供應商,Auth 程式庫可以從本機檔案 (檔案來源憑證)、本機伺服器 (網址來源憑證),或 X.509 憑證和私密金鑰組合 (X.509 憑證來源憑證) 擷取 OIDC 權杖。
檔案來源憑證
如果是以檔案為來源的憑證,背景程序必須在 OIDC 權杖到期前,持續以新權杖重新整理檔案位置。如果權杖的效期為一小時,您必須每小時更新檔案中的權杖。您可以直接以純文字或 JSON 格式儲存權杖。
如要產生以檔案為來源的 OIDC 設定,請執行下列指令:
# Generate an OIDC configuration file for file-sourced credentials.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>OIDC_PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--credential-source-file <var>PATH_TO_OIDC_ID_TOKEN</var> \
# Optional arguments for file types. Default is "text":
# --credential-source-type "json" \
# Optional argument for the field that contains the OIDC credential.
# This is required for json.
# --credential-source-field-name "id_token" \
--output-file /path/to/generated/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。OIDC_PROVIDER_ID:OIDC 提供者 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。PATH_TO_OIDC_ID_TOKEN:用於擷取 OIDC 權杖的路徑。
這個指令會在指定的輸出檔案中產生設定檔。
網址來源憑證
如要使用網址來源的憑證,本機伺服器必須代管 GET 端點,以純文字或 JSON 格式提供 OIDC 權杖。如果端點需要,您可以指定要在權杖要求中傳送的其他 HTTP 標頭。
如要產生以網址為來源的 OIDC 工作負載身分設定,請執行下列指令:
# Generate an OIDC configuration file for URL-sourced credentials.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>OIDC_PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--credential-source-url <var>URL_TO_GET_OIDC_TOKEN</var> \
--credential-source-headers <var>HEADER_KEY=HEADER_VALUE</var> \
# Optional arguments for file types. Default is "text":
# --credential-source-type "json" \
# Optional argument for the field that contains the OIDC credential.
# This is required for json.
# --credential-source-field-name "id_token" \
--output-file /path/to/generated/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。OIDC_PROVIDER_ID:OIDC 提供者 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。URL_TO_GET_OIDC_TOKEN:要呼叫以擷取 OIDC 權杖的本機伺服器端點網址。HEADER_KEY和HEADER_VALUE:要傳送至URL_TO_GET_OIDC_TOKEN的 GET 要求的其他標頭鍵/值組合,例如Metadata-Flavor=Google。
您現在可以使用 Auth 程式庫,從 OIDC 提供者呼叫Google Cloud 資源。
使用 X.509 憑證來源的憑證存取資源
如果是以 X.509 憑證為來源的憑證,驗證程式庫會使用 X.509 憑證和私密金鑰,證明應用程式的身分。X.509 憑證有到期日,必須在到期前更新,才能維持存取權。
詳情請參閱官方說明文件。
產生 X.509 聯盟的設定檔
如要設定以 X.509 憑證為來源的憑證,請產生兩個不同的檔案:主要憑證設定檔和憑證設定檔。
- 主要憑證設定檔包含驗證所需的必要中繼資料。這個檔案也會參照憑證設定檔。
- 憑證設定檔會指定 X.509 憑證、私密金鑰和信任鏈結的檔案路徑。
您可以使用 gcloud iam workload-identity-pools create-cred-config 指令建立這兩者。
gcloud 建立憑證設定檔的位置取決於您是否使用 --credential-cert-configuration-output-file 旗標。
預設行為 (建議)
如果省略 --credential-cert-configuration-output-file 標記,gcloud 會在預設的知名位置建立憑證設定檔,Auth 程式庫可自動探索該位置。這個方法適用於大多數用途。預設憑證設定檔名為 config.json,預設憑證設定檔名為 certificate_config.json。
舉例來說,執行下列指令即可使用預設行為建立設定檔:
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--credential-cert-path "<var>PATH_TO_CERTIFICATE</var>" \
--credential-cert-private-key-path "<var>PATH_TO_PRIVATE_KEY</var>" \
--credential-cert-trust-chain-path "<var>PATH_TO_TRUST_CHAIN</var>" \
--output-file /path/to/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。PROVIDER_ID:供應商 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。PATH_TO_CERTIFICATE:葉片 X.509 憑證所在的路徑。PATH_TO_PRIVATE_KEY:葉子憑證對應私密金鑰所在的路徑。PATH_TO_TRUST_CHAIN:X.509 憑證信任鏈檔案的路徑。這個檔案應為 PEM 格式,其中包含完成葉片憑證與 Workload Identity Federation 集區中設定的信任儲存庫之間信任鏈結所需的任何中繼憑證。這個檔案中的葉子憑證為選填。
這項指令會產生下列結果:
/path/to/config.json:在您指定的路徑中建立。這個檔案會包含"use_default_certificate_config": true,指示用戶端在預設路徑尋找憑證設定。certificate_config.json:在預設的 Google Cloud CLI 設定路徑中建立,通常是 Linux 和 macOS 上的~/.config/gcloud/certificate_config.json,或是 Windows 上的%APPDATA%\gcloud\certificate_config.json。
自訂位置行為
如需將憑證設定檔儲存在非預設位置,請使用 --credential-cert-configuration-output-file 旗標。
範例指令 (自訂位置):
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--credential-cert-path "<var>PATH_TO_CERTIFICATE</var>" \
--credential-cert-private-key-path "<var>PATH_TO_PRIVATE_KEY</var>" \
--credential-cert-trust-chain-path "<var>PATH_TO_TRUST_CHAIN</var>" \
--credential-cert-configuration-output-file "/custom/path/cert_config.json" \
--output-file /path/to/config.json
這項指令會產生下列結果:
/path/to/config.json:在您指定的路徑中建立。這個檔案會包含指向自訂路徑的"certificate_config_location"欄位。cert_config.json:在/custom/path/cert_config.json建立,如標記所指定。
您現在可以使用 Auth 程式庫,透過 X.509 憑證來源的憑證呼叫Google Cloud 資源。
搭配 OIDC 和 SAML 使用可執行檔來源的憑證
如果是可執行檔來源的憑證,系統會使用本機可執行檔擷取第三方權杖。可執行檔必須以 JSON 格式向 stdout 提供有效的未過期 OIDC ID 權杖或 SAML 聲明。
如要使用可執行檔來源的憑證,GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES 環境變數必須設為 1。
如要產生可執行檔來源的工作負載身分識別設定,請執行下列指令:
# Generate a configuration file for executable-sourced credentials.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>PROVIDER_ID</var> \
--service-account=<var>SERVICE_ACCOUNT_EMAIL</var> \
--subject-token-type=<var>SUBJECT_TOKEN_TYPE</var> \
# The absolute path for the program, including arguments.
# e.g. --executable-command="/path/to/command --foo=bar"
--executable-command=<var>EXECUTABLE_COMMAND</var> \
# Optional argument for the executable timeout. Defaults to 30s.
# --executable-timeout-millis=<var>EXECUTABLE_TIMEOUT</var> \
# Optional argument for the absolute path to the executable output file.
# See below on how this argument impacts the library behaviour.
# --executable-output-file=<var>EXECUTABLE_OUTPUT_FILE</var> \
--output-file /path/to/generated/config.json
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。PROVIDER_ID:OIDC 或 SAML 提供者 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。SUBJECT_TOKEN_TYPE:主體權杖類型。EXECUTABLE_COMMAND:要執行的完整指令,包括引數。必須是程式的絕對路徑。
--executable-timeout-millis 旗標為選用項目,可指定 Auth 程式庫等待可執行檔完成作業的時間長度 (以毫秒為單位)。如未提供,則預設為 30 秒。上限為兩分鐘,下限為五秒。
選用的 --executable-output-file 旗標會指定路徑,用於快取可執行檔的第三方憑證回應。由於授權程式庫會先檢查這個檔案是否含有有效且未過期的憑證,再執行可執行檔,因此快取有助於提升效能。如果存在有效的快取憑證,程式庫就會使用這些憑證,避免執行不必要的執行檔。
可執行檔必須將憑證回應寫入這個檔案。驗證程式庫只會從這個位置讀取資料。檔案內容必須符合預期的 JSON 格式。
如要擷取第三方權杖,程式庫會使用指定的指令執行可執行檔。可執行檔的輸出內容必須符合下列範例中指定的回覆格式,且必須將回覆輸出至 stdout。
以下是可執行的 OIDC 成功回應範例:
{
"version": 1,
"success": true,
"token_type": "urn:ietf:params:oauth:token-type:id_token",
"id_token": "HEADER.PAYLOAD.SIGNATURE",
"expiration_time": 1620499962
}
以下是可執行的 SAML 回應範例:
{
"version": 1,
"success": true,
"token_type": "urn:ietf:params:oauth:token-type:saml2",
"saml_response": "...",
"expiration_time": 1620499962
}
在憑證設定中,使用 --executable-output-file 引數指定輸出檔案時,成功的執行檔回應必須包含 expiration_time 欄位。這樣一來,驗證程式庫就能有效快取及管理儲存在該檔案中的憑證效期。
可執行的錯誤回應範例如下:
{
"version": 1,
"success": false,
"code": "401",
"message": "Caller not authorized."
}
這些都是錯誤回應的必填欄位。程式庫會使用程式碼和訊息欄位,做為擲回例外狀況的一部分。
回應格式欄位摘要:
* version:JSON 輸出版本。系統僅支援版本 1。
* success:如果為 true,回應必須包含第三方權杖和權杖類型。如果憑證設定中指定了輸出檔案,回應也必須包含 expiration_time 欄位。可執行檔也必須以結束代碼 0 結束。如果為 false,回應必須包含錯誤代碼和訊息欄位,並以非零值結束。* token_type:這個欄位會指定第三方主體權杖類型。必須是 urn:ietf:params:oauth:token-type:jwt、urn:ietf:params:oauth:token-type:id_token 或 urn:ietf:params:oauth:token-type:saml2。* id_token:第三方 OIDC 權杖。
* saml_response:第三方 SAML 回應。* expiration_time:第三方主體權杖的到期時間 (以秒為單位),(Unix Epoch 紀元時間)。* code:錯誤代碼字串。
* message:錯誤訊息。
所有回應類型都必須包含 version 和 success 欄位。
* 成功的回應必須包含 token_type,以及 id_token 或 saml_response 其中之一。如果憑證設定中指定了輸出檔案,則也必須提供 expiration_time 欄位。* 錯誤回應必須包含 code 和 message 欄位。
程式庫執行可執行檔時,會填入下列環境變數:
GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE:憑證設定中的目標對象欄位。一律會顯示。GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE:這個預期的主體權杖類型。 一律會顯示。GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL:服務帳戶電子郵件地址。只有在使用服務帳戶模擬功能時才會顯示。GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE:憑證設定的輸出檔案位置。只有在憑證設定中指定時才會顯示。
可執行檔可以使用這些環境變數,避免對這些值進行硬式編碼。
安全性考量
建議採取下列安全措施:
- 防止惡意程序執行可執行檔,因為這會透過
stdout將機密憑證輸出至這些程序及其使用者。 - 防止惡意程序變更設定或可執行檔的叫用。
由於使用可執行檔來源憑證相當複雜,因此我們強烈建議您使用其他支援的機制 (例如檔案或網址來源) 提供第三方憑證,除非這些機制不符合您的特定需求。
您現在可以使用 Auth 程式庫,從 OIDC 或 SAML 提供者呼叫Google Cloud 資源。
使用 OIDC 和 SAML 自訂供應商
建構 IdentityPoolCredentials 時,可以使用 IdentityPoolSubjectTokenSupplier 的自訂實作項目,提供可交換 Google Cloud 存取權杖的主體權杖。供應商必須在 Google Cloud憑證呼叫時,傳回有效且未過期的主體權杖。
IdentityPoolCredentials 請勿快取傳回的權杖,因此請在權杖供應商中實作快取邏輯,避免對相同主體權杖提出多項要求。
import java.io.IOException;
public class CustomTokenSupplier implements IdentityPoolSubjectTokenSupplier {
@Override
public String getSubjectToken(ExternalAccountSupplierContext context) throws IOException {
// Any call to the supplier passes a context object with the requested
// audience and subject token type.
string audience = context.getAudience();
string tokenType = context.getSubjectTokenType();
try {
// Return a valid, unexpired token for the requested audience and token type.
// Note that IdentityPoolCredentials don't cache the subject token so
// any caching logic needs to be implemented in the token supplier.
return retrieveToken(audience, tokenType);
} catch (Exception e) {
// If token is unavailable, throw IOException.
throw new IOException(e);
}
}
private String retrieveToken(string tokenType, string audience) {
// Retrieve a subject token of the requested type for the requested audience.
}
}
CustomTokenSupplier tokenSupplier = new CustomTokenSupplier();
IdentityPoolCredentials identityPoolCredentials =
IdentityPoolCredentials.newBuilder()
.setSubjectTokenSupplier(tokenSupplier) // Sets the token supplier.
.setAudience(...) // Sets the Google Cloud audience.
.setSubjectTokenType(SubjectTokenTypes.JWT) // Sets the subject token type.
.build();
觀眾所在位置:
//iam.googleapis.com/projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>WORKLOAD_POOL_ID</var>/providers/<var>PROVIDER_ID</var>
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudWORKLOAD_POOL_ID:Workload Identity Pool ID。PROVIDER_ID:供應商 ID。
您也可以使用 gcloud CLI 產生憑證設定檔,找出對象、服務帳戶模擬網址和任何其他建構工具欄位的值。
搭配 AWS 使用自訂供應商
初始化 AwsCredentials 時,可以提供 AwsSecurityCredentialsSupplier 的自訂實作項目。如果提供 AwsCredentials 執行個體,該執行個體會將 AWS 安全性憑證的擷取作業延後至供應商,以換取Google Cloud 存取權杖。供應商必須在 Google Cloud 憑證呼叫時,傳回有效且未過期的 AWS 安全性憑證。
AwsCredentials 請勿快取傳回的 AWS 安全性憑證或區域,因此請在供應商中實作快取邏輯,避免對相同資源提出多個要求。
class CustomAwsSupplier implements AwsSecurityCredentialsSupplier {
@Override
AwsSecurityCredentials getAwsSecurityCredentials(ExternalAccountSupplierContext context) throws IOException {
// Any call to the supplier passes a context object with the requested
// audience.
String audience = context.getAudience();
try {
// Return valid, unexpired AWS security credentials for the requested audience.
// Note that AwsCredentials don't cache the AWS security credentials so
// any caching logic needs to be implemented in the credentials' supplier.
return retrieveAwsSecurityCredentials(audience);
} catch (Exception e) {
// If credentials are unavailable, throw IOException.
throw new IOException(e);
}
}
@Override
String getRegion(ExternalAccountSupplierContext context) throws IOException {
try {
// Return a valid AWS region. i.e. "us-east-2".
// Note that AwsCredentials don't cache the region so
// any caching logic needs to be implemented in the credentials' supplier.
return retrieveAwsRegion();
} catch (Exception e) {
// If region is unavailable, throw IOException.
throw new IOException(e);
}
}
private AwsSecurityCredentials retrieveAwsSecurityCredentials(string audience) {
// Retrieve Aws security credentials for the requested audience.
}
private String retrieveAwsRegion() {
// Retrieve current AWS region.
}
}
CustomAwsSupplier awsSupplier = new CustomAwsSupplier();
AwsCredentials credentials = AwsCredentials.newBuilder()
.setSubjectTokenType(SubjectTokenTypes.AWS4) // Sets the subject token type.
.setAudience(...) // Sets the Google Cloud audience.
.setAwsSecurityCredentialsSupplier(supplier) // Sets the supplier.
.build();
目標對象所在位置:
//iam.googleapis.com/projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>WORKLOAD_POOL_ID</var>/providers/<var>PROVIDER_ID</var>
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudWORKLOAD_POOL_ID:Workload Identity Pool ID。PROVIDER_ID:供應商 ID。
您也可以使用 gcloud CLI 產生憑證設定檔,找出對象、服務帳戶模擬網址和任何其他建構工具欄位的值。
可設定的權杖生命週期
使用服務帳戶模擬功能,透過 workload identity federation 建立憑證設定時,您可以提供選用引數,設定服務帳戶存取權杖生命週期。
如要產生可設定權杖生命週期的設定,請執行下列指令 (這個範例使用 AWS 設定,但權杖生命週期可為所有 Workload Identity 聯盟供應商設定):
# Generate an AWS configuration file with configurable token lifetime.
gcloud iam workload-identity-pools create-cred-config \
projects/<var>PROJECT_NUMBER</var>/locations/global/workloadIdentityPools/<var>POOL_ID</var>/providers/<var>AWS_PROVIDER_ID</var> \
--service-account <var>SERVICE_ACCOUNT_EMAIL</var> \
--aws \
--output-file /path/to/generated/config.json \
--service-account-token-lifetime-seconds <var>TOKEN_LIFETIME</var>
更改下列內容:
PROJECT_NUMBER:專案編號。 Google CloudPOOL_ID:Workload Identity Pool ID。AWS_PROVIDER_ID:AWS 供應商 ID。SERVICE_ACCOUNT_EMAIL:要模擬的服務帳戶電子郵件地址。TOKEN_LIFETIME:所選服務帳戶存取權杖的生命週期,以秒為單位。
service-account-token-lifetime-seconds 是選用旗標。如未提供,旗標會預設為一小時。允許的最小值為 600 (10 分鐘),允許的最大值為 43200 (12 小時)。如要將生命週期延長至超過一小時,您必須在強制執行 constraints/iam.allowServiceAccountCredentialLifetimeExtension 限制的機構政策服務中,將服務帳戶新增為允許值。
設定較短的生命週期 (例如 10 分鐘) 會導致程式庫每 10 分鐘啟動一次完整的權杖交換流程。即使第三方權杖未過期,系統也會呼叫第三方權杖供應商。
使用外部帳戶授權使用者工作團隊憑證
外部帳戶授權使用者憑證可讓您使用 gcloud CLI,透過網頁瀏覽器登入外部身分提供者帳戶,並建立驗證程式庫使用的設定。
如要產生外部帳戶授權使用者員工身分設定,請執行下列指令:
gcloud auth application-default login --login-config=LOGIN_CONFIG
請替換下列變數:
LOGIN_CONFIG:使用 Google Cloud 控制台或 gcloud iam workforce-pools create-login-config 產生的登入設定檔
這會開啟瀏覽器流程,讓您使用已設定的第三方身分識別資訊提供者登入。接著,它會將外部帳戶授權使用者設定儲存在已知的 ADC 位置。
然後,Auth 程式庫會使用設定中提供的更新權杖產生及更新存取權杖,以呼叫 Google Cloud 服務。
更新權杖的預設生命週期為一小時。完成後,您需要使用 gcloud CLI 產生新的設定。如要修改生命週期,請變更工作團隊集區的工作階段持續時間,最長可設為 12 小時。
使用外部身分
您可以搭配 Application Default Credentials 使用外部身分。如要搭配應用程式預設憑證使用外部身分,請按照「工作負載身分聯盟」一節的說明,為外部身分產生 JSON 憑證設定檔。產生後,請將這個檔案的路徑儲存在 GOOGLE_APPLICATION_CREDENTIALS 環境變數中。
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/config.json
程式庫現在可以選擇正確的用戶端類型,並從設定檔提供的環境初始化憑證。
GoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();
String projectId = "your-project-id";
String url = "https://storage.googleapis.com/storage/v1/b?project=" + projectId;
HttpCredentialsAdapter credentialsAdapter = new HttpCredentialsAdapter(googleCredentials);
HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory(credentialsAdapter);
HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url));
JsonObjectParser parser = new JsonObjectParser(GsonFactory.getDefaultInstance());
request.setParser(parser);
HttpResponse response = request.execute();
System.out.println(response.parseAsString());
您也可以使用產生的設定檔,明確初始化外部帳戶用戶端。
ExternalAccountCredentials credentials =
ExternalAccountCredentials.fromStream(new FileInputStream("/path/to/credentials.json"));
安全性考量
這個程式庫不會對憑證設定的 token_url、token_info_url 或 service_account_impersonation_url 欄位執行任何驗證。除非您確認網址欄位指向 googleapis.com 網域,否則不建議使用您未透過 gcloud CLI 產生的憑證設定。
透過憑證存取權範圍縮小權限範圍
使用憑證存取權界線縮減範圍,可限制短期憑證用於 Cloud Storage 的身分與存取權管理 (IAM) 權限。這包括建立 CredentialAccessBoundary,定義適用於範圍縮減權杖的限制。使用範圍縮減的憑證可確保傳輸中的權杖一律具備最低權限。請參閱「最低權限原則」。
建立 CredentialAccessBoundary
憑證存取權界線會指定新建立的憑證可存取哪些資源。此外,也指定每個資源可用的權限上限。包含一或多個 AccessBoundaryRule 物件。
下列程式碼片段說明如何使用一個 AccessBoundaryRule 初始化 CredentialAccessBoundary。這項規則指定縮減範圍的權杖只能讀取值區 bucket-123 中以 customer-a 開頭的物件。
// Create the AccessBoundaryRule.
String availableResource = "//storage.googleapis.com/projects/_/buckets/bucket-123";
String availablePermission = "inRole:roles/storage.objectViewer";
String expression = "resource.name.startsWith('projects/_/buckets/bucket-123/objects/customer-a')";
CredentialAccessBoundary.AccessBoundaryRule rule =
CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
.setAvailableResource(availableResource)
.addAvailablePermission(availablePermission)
.setAvailabilityCondition(
CredentialAccessBoundary.AccessBoundaryRule.AvailabilityCondition.newBuilder().setExpression(expression).build())
.build();
// Create the CredentialAccessBoundary with the rule.
CredentialAccessBoundary credentialAccessBoundary =
CredentialAccessBoundary.newBuilder().addRule(rule).build();
常見使用模式
常見的使用模式是透過具有更高存取權的權杖代理人。這個中介服務會根據較高存取權來源憑證,產生範圍縮小的憑證。然後,透過安全驗證管道將範圍縮減的短期存取權杖傳遞給權杖消費者,以限制存取 Google Cloud儲存空間資源。
產生範圍縮減的權杖
您可以使用 CredentialAccessBoundary,透過下列兩種方式產生範圍縮減的權杖:
伺服器端 (使用
DownscopedCredentials):用戶端每次需要範圍縮減的權杖時,都會呼叫安全權杖服務 (STS)。這項功能適用於憑證存取權範圍規則不常變更的應用程式,或是您多次重複使用單一縮小範圍的憑證。請注意,每次變更規則時,您都必須向 STS 發出新的呼叫。這個方法可在google-auth-library-oauth2-http程式庫中使用,不需要任何額外的依附元件。這樣一來,整合作業就會更簡單。如果您的用途不需要用戶端做法的特定優點,就很適合採用這個方法。用戶端 (使用
ClientSideCredentialAccessBoundaryFactory):用戶端會擷取一次加密編譯資料,然後在本機產生多個範圍縮減的權杖。這樣可減少對 STS 的呼叫,且在憑證存取邊界規則經常變更時,效率會更高,因為用戶端不必在每次規則變更時都聯絡 STS。如果應用程式需要產生許多專屬的範圍縮減權杖,這種做法也更有效率。這個方法適用於google-auth-library-cab-token-generator模組。不過,這個模組有自己的依附元件集。這些依附元件可能會增加專案的複雜度。如果主要考量是盡量減少 STS 呼叫次數,並產生大量不重複的權杖,請考慮採用這種做法。您也需要管理額外的依附元件。
伺服器端 CAB
DownscopedCredentials 類別可用於從來源憑證和 CredentialAccessBoundary 產生範圍縮減的存取權杖。
// Retrieve the source credentials from ADC.
GoogleCredentials sourceCredentials = GoogleCredentials.getApplicationDefault()
.createScoped("https://www.googleapis.com/auth/cloud-platform");
// Create an Access Boundary Rule which will restrict the downscoped token to having read-only
// access to objects starting with "customer-a" in bucket "bucket-123".
String availableResource = "//storage.googleapis.com/projects/_/buckets/bucket-123";
String availablePermission = "inRole:roles/storage.objectViewer";
String expression = "resource.name.startsWith('projects/_/buckets/bucket-123/objects/customer-a')";
CredentialAccessBoundary.AccessBoundaryRule rule =
CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
.setAvailableResource(availableResource)
.addAvailablePermission(availablePermission)
.setAvailabilityCondition(
new AvailabilityCondition(expression, /* title= */ null, /* description= */ null))
.build();
// Initialize the DownscopedCredentials class.
DownscopedCredentials downscopedCredentials =
DownscopedCredentials.newBuilder()
.setSourceCredential(sourceCredentials)
.setCredentialAccessBoundary(CredentialAccessBoundary.newBuilder().addRule(rule).build())
.build();
// Retrieve the downscoped access token.
// You will need to pass this to the Token Consumer.
AccessToken downscopedAccessToken = downscopedCredentials.refreshAccessToken();
用戶端 CAB
如果是用戶端 CAB,則會使用來源憑證搭配 ClientSideCredentialAccessBoundaryFactory。初始化工廠後,您可以透過不同的 CredentialAccessBoundary 物件重複呼叫 generateToken() 方法,建立多個範圍受限的權杖。
// Retrieve the source credentials from ADC.
GoogleCredentials sourceCredentials = GoogleCredentials.getApplicationDefault()
.createScoped("https://www.googleapis.com/auth/cloud-platform");
// Create an Access Boundary Rule which will restrict the downscoped token to having read-only
// access to objects starting with "customer-a" in bucket "bucket-123".
String availableResource = "//storage.googleapis.com/projects/_/buckets/bucket-123";
String availablePermission = "inRole:roles/storage.objectViewer";
String expression = "resource.name.startsWith('projects/_/buckets/bucket-123/objects/customer-a')";
CredentialAccessBoundary.AccessBoundaryRule rule =
CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
.setAvailableResource(availableResource)
.addAvailablePermission(availablePermission)
.setAvailabilityCondition(
new AvailabilityCondition(expression, /* title= */ null, /* description= */ null))
.build();
// Initialize the ClientSideCredentialAccessBoundaryFactory.
ClientSideCredentialAccessBoundaryFactory factory =
ClientSideCredentialAccessBoundaryFactory.newBuilder()
.setSourceCredential(sourceCredentials)
.build();
// Create the CredentialAccessBoundary with the rule.
CredentialAccessBoundary credentialAccessBoundary =
CredentialAccessBoundary.newBuilder().addRule(rule).build();
// Generate the downscoped access token.
// You will need to pass this to the Token Consumer.
AccessToken downscopedAccessToken = factory.generateToken(credentialAccessBoundary);
使用範圍縮減的存取權杖
您可以在私人網路的伺服器上設定權杖代理程式。同一網路中的各種工作負載 (權杖消費者) 會將經過驗證的要求傳送至該中介服務,以取得範圍縮減的權杖。這些權杖可讓他們存取或修改特定 Google Cloud 儲存空間 bucket。
代理人會例項化範圍縮小的憑證例項,這些例項可產生範圍縮小的短期存取權杖。然後將這些權杖傳遞給權杖消費者。
Token Consumer 可以使用 OAuth2Credentials 或 OAuth2CredentialsWithRefresh,存取這些範圍縮減的存取權杖。接著,您可以使用這項憑證初始化儲存空間用戶端例項,存取受限的儲存空間資源。 Google Cloud
// You can pass an `OAuth2RefreshHandler` to `OAuth2CredentialsWithRefresh` that will allow the
// library to seamlessly handle downscoped token refreshes on expiration.
OAuth2CredentialsWithRefresh.OAuth2RefreshHandler handler =
new OAuth2CredentialsWithRefresh.OAuth2RefreshHandler() {
@Override
public AccessToken refreshAccessToken() {
// Retrieve the token from your Token Broker.
return accessToken;
}
};
// The downscoped token is retrieved from the token broker.
AccessToken downscopedToken = handler.refreshAccessToken();
// Build the OAuth2CredentialsWithRefresh from the downscoped token and pass a refresh handler
// to handle token expiration. Passing the original downscoped token or the expiry here is optional,
// because the refresh_handler will generate the downscoped token on demand.
OAuth2CredentialsWithRefresh credentials =
OAuth2CredentialsWithRefresh.newBuilder()
.setAccessToken(downscopedToken)
.setRefreshHandler(handler)
.build();
// Use the credentials with the Cloud Storage SDK.
StorageOptions options = StorageOptions.newBuilder().setCredentials(credentials).build();
Storage storage = options.getService();
// Call Cloud Storage APIs.
// Because we passed the downscoped credential, we will have limited read-only access to objects
// starting with "customer-a" in bucket "bucket-123".
storage.get(...)
只有 Cloud Storage 支援憑證存取邊界,其他Google Cloud 服務不支援這項功能。
使用 google-http-client 的憑證
com.google.auth:google-auth-library-oauth2-http 提供的憑證可用於 Google 的 HTTP 型用戶端。Google 的 HTTP 型用戶端提供 HttpCredentialsAdapter,可做為建構工具的最後一個引數 HttpRequestInitializer。
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.services.bigquery.Bigquery;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
Bigquery bq = new Bigquery.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
.setApplicationName(APPLICATION_NAME)
.build();
驗證 JWT 權杖 (Beta 版功能)
如要驗證 JWT 權杖,請使用 TokenVerifier 類別。
驗證簽章
如要驗證簽章,請使用預設的 TokenVerifier:
import com.google.api.client.json.webtoken.JsonWebSignature;
import com.google.auth.oauth2.TokenVerifier;
TokenVerifier tokenVerifier = TokenVerifier.newBuilder().build();
try {
JsonWebSignature jsonWebSignature = tokenVerifier.verify(tokenString);
// Optionally, verify additional claims.
if (!"expected-value".equals(jsonWebSignature.getPayload().get("additional-claim"))) {
// Handle custom verification error.
}
} catch (TokenVerifier.VerificationException e) {
// The token is invalid.
}
自訂 TokenVerifier
如要自訂 TokenVerifier,請使用相關建構工具例項化:
import com.google.api.client.json.webtoken.JsonWebSignature;
import com.google.auth.oauth2.TokenVerifier;
TokenVerifier tokenVerifier = TokenVerifier.newBuilder()
.setAudience("audience-to-verify")
.setIssuer("issuer-to-verify")
.build();
try {
JsonWebSignature jsonWebSignature = tokenVerifier.verify(tokenString);
// Optionally, verify additional claims.
if (!"expected-value".equals(jsonWebSignature.getPayload().get("additional-claim"))) {
// Handle custom verification error.
}
} catch (TokenVerifier.VerificationException e) {
// The token is invalid.
}
如需更多選項,請參閱 TokenVerifier.Builder 說明文件。
google-auth-library-credentials
這個構件包含 Google 憑證的基礎類別和介面:
Credentials:這是授權身分的基本類別。這個類別的實作項目可以授權您的應用程式。RequestMetadataCallback:這是回呼的介面,可接收非同步Credentials.getRequestMetadata(URI, Executor, RequestMetadataCallback)的結果。ServiceAccountSigner:這是服務帳戶簽署者的介面。這個類別的實作項目可使用與 Google 服務帳戶相關聯的憑證,簽署位元組陣列。
google-auth-library-appengine
這個構件依附於 App Engine SDK (appengine-api-1.0-sdk)。請僅將這個構件用於在 App Engine 環境中執行的應用程式,這些環境使用 urlfetch。您可以使用 AppEngineCredentials 類別,透過 AppIdentityService 的例項授權 App Engine 應用程式。
用法:
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.auth.Credentials;
import com.google.auth.appengine.AppEngineCredentials;
AppIdentityService appIdentityService = AppIdentityServiceFactory.getAppIdentityService();
Credentials credentials =
AppEngineCredentials.newBuilder()
.setScopes(...)
.setAppIdentityService(appIdentityService)
.build();
google-auth-library-cab-token-generator
這個模組提供 ClientSideCredentialAccessBoundaryFactory 類別,可讓您使用憑證存取邊界,在用戶端產生 Cloud Storage 的範圍縮減權杖。如果應用程式需要經常變更憑證存取權界線規則,或產生許多獨特的範圍縮減權杖,這個方法就特別實用,因為這樣可以盡量減少對安全權杖服務 (STS) 的呼叫次數。如需使用範例,請參閱「用戶端 CAB」一節。這個模組有自己的依附元件集。請評估用戶端範圍縮減的優點,是否大於特定用途的複雜度。