使用服務帳戶驗證工作負載,以便存取 Google Cloud API

本頁說明如何使用服務帳戶,讓在虛擬機器 (VM) 執行個體上執行的應用程式向 Google Cloud API 進行驗證,並授權存取資源。

如要使用服務帳戶進行驗證,請先確認 VM 已設定為使用服務帳戶。如要這樣做,請完成下列其中一項程序:

事前準備

  • 查看服務帳戶總覽
  • 如果尚未設定驗證,請先完成設定。 驗證可確認您的身分,以便存取 Google Cloud 服務和 API。如要從本機開發環境執行程式碼或範例,請選取下列其中一個選項,向 Compute Engine 進行驗證:

    如要在本機開發環境中使用本頁的 Python 範例,請安裝並初始化 gcloud CLI,然後使用您的使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

    3. 如果您使用本機殼層,請為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果您使用 Cloud Shell,則不需要執行這項操作。

      如果系統傳回驗證錯誤,且您使用外部識別資訊提供者 (IdP),請確認您已 使用聯合身分登入 gcloud CLI

    詳情請參閱 這篇文章,瞭解如何設定本機開發環境的驗證機制。

總覽

設定 VM 執行個體以服務帳戶身分執行後,VM 執行個體上執行的應用程式可以透過下列其中一種方法進行驗證:

使用服務帳戶憑證驗證應用程式

設定執行個體以服務帳戶身分執行後,您可以使用該服務帳戶的憑證,驗證在執行個體上執行的應用程式。

透過用戶端程式庫驗證應用程式

用戶端程式庫可以使用應用程式預設憑證向 Google API 進行驗證,然後傳送要求給這些 API。應用程式預設憑證可讓應用程式自動從多個來源取得憑證,方便您在本機測試應用程式,然後再將其部署至 Compute Engine 執行個體,過程中無須變更應用程式程式碼。

如要瞭解如何設定應用程式預設憑證,請參閱「為應用程式預設憑證提供憑證」。

本範例使用 Python 用戶端程式庫向 Cloud Storage API 進行驗證,並要求列出專案中的值區。本範例採用以下程序:

  1. 為 Cloud Storage API 取得必要的驗證憑證,並使用 build() 方法和這些憑證初始化 Cloud Storage 服務。
  2. 列出 Cloud Storage 中的值區。

您可以在有權管理 Cloud Storage 中值區的執行個體上執行本範例。

import argparse
from typing import List

from google.cloud import storage


def create_client() -> storage.Client:
    """
    Construct a client object for the Storage API using the
    application default credentials.

    Returns:
        Storage API client object.
    """
    # Construct the service object for interacting with the Cloud Storage API -
    # the 'storage' service, at version 'v1'.
    # Authentication is provided by application default credentials.
    # When running locally, these are available after running
    # `gcloud auth application-default login`. When running on Compute
    # Engine, these are available from the environment.
    return storage.Client()


def list_buckets(client: storage.Client, project_id: str) -> List[storage.Bucket]:
    """
    Retrieve bucket list of a project using provided client object.


    Args:
        client: Storage API client object.
        project_id: name of the project to list buckets from.

    Returns:
        List of Buckets found in the project.
    """
    buckets = client.list_buckets()
    return list(buckets)


def main(project_id: str) -> None:
    client = create_client()
    buckets = list_buckets(client, project_id)
    print(buckets)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("project_id", help="Your Google Cloud Project ID.")

    args = parser.parse_args()

    main(args.project_id)

直接透過存取憑證驗證應用程式

對於大多數應用程式,您可以使用應用程式預設憑證進行驗證,這項憑證會為您尋找憑證並管理權杖。不過,如果應用程式要求您提供 OAuth2 存取權杖,Compute Engine 可讓您從中繼資料伺服器取得存取權杖,供應用程式使用。

您有幾種方法可以取得及使用這些存取憑證來驗證應用程式。例如,您可以使用 curl 建立簡單的要求,或使用 Python 等更有彈性的程式設計語言。

cURL

如要使用 curl 要求存取憑證並傳送要求給 API,請執行下列操作:

  1. 在應用程式執行所在的執行個體,執行下列指令,透過查詢中繼資料伺服器來取得存取憑證:

    $ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google"

    這個要求會傳回類似以下的回應:

    {
          "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
          "expires_in":3599,
          "token_type":"Bearer"
     }

    API 要求必須包含 access_token 值,而非整個回應。如果您已安裝 jq 指令列 JSON 處理器,可以使用下列指令從回應中擷取存取權杖值:

    $ ACCESS_TOKEN=`curl \
    "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google" | jq -r '.access_token'`
    
  2. 複製回應中的 access_token 屬性值,然後用它傳送要求給 API。例如,以下要求會列印出您在特定區域中的專案的執行個體清單:

    $ curl https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances \
    -H "Authorization":"Bearer ACCESS_TOKEN"
    

    更改下列內容:

    • PROJECT_ID:這項要求的專案 ID。
    • ZONE:要列出 VM 的可用區。
    • ACCESS_TOKEN:您在上一個步驟中取得的存取權杖值。

    如要進一步瞭解您可以在要求設定哪些參數,請參閱系統參數說明文件。

Python

本範例將示範如何在 Python 應用程式中要求 Cloud Storage API 存取憑證。本範例採用以下程序:

  1. 向中繼資料伺服器要求憑證。
  2. 從伺服器的回應中擷取存取憑證。
  3. 使用該存取憑證向 Cloud Storage 發出要求。
  4. 如果要求成功,指令碼會列印回應。

import argparse

import requests


METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/"
METADATA_HEADERS = {"Metadata-Flavor": "Google"}
SERVICE_ACCOUNT = "default"


def get_access_token() -> str:
    """
    Retrieves access token from the metadata server.

    Returns:
        The access token.
    """
    url = f"{METADATA_URL}instance/service-accounts/{SERVICE_ACCOUNT}/token"

    # Request an access token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    r.raise_for_status()

    # Extract the access token from the response.
    access_token = r.json()["access_token"]

    return access_token


def list_buckets(project_id: str, access_token: str) -> dict:
    """
    Calls Storage API to retrieve a list of buckets.

    Args:
        project_id: name of the project to list buckets from.
        access_token: access token to authenticate with.

    Returns:
        Response from the API.
    """
    url = "https://www.googleapis.com/storage/v1/b"
    params = {"project": project_id}
    headers = {"Authorization": f"Bearer {access_token}"}

    r = requests.get(url, params=params, headers=headers)
    r.raise_for_status()

    return r.json()


def main(project_id: str) -> None:
    """
    Retrieves access token from metadata server and uses it to list
    buckets in a project.

    Args:
        project_id: name of the project to list buckets from.
    """
    access_token = get_access_token()
    buckets = list_buckets(project_id, access_token)
    print(buckets)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("project_id", help="Your Google Cloud project ID.")

    args = parser.parse_args()

    main(args.project_id)

存取憑證會在短時間內失效。中繼資料伺服器會快取存取權杖,直到權杖到期前 5 分鐘為止。如果權杖無法快取,超過每秒 50 個查詢的要求可能會受到頻率限制。應用程式必須具備有效的存取權杖,才能順利呼叫 API。

使用服務帳戶的執行個體上的驗證工具

某些應用程式可能會使用 gcloud CLI 的指令,這些指令會預設包含在多數的 Compute Engine 映像檔中。gcloud CLI 會自動識別執行個體的服務帳戶,以及授予服務帳戶的相關權限。具體來說,如果您已為服務帳戶授予正確的角色,就可以使用來自執行個體的 gcloud CLI,而無須使用 gcloud auth login

這個服務帳戶的識別作業會自動啟動,並且只適用於執行個體包含的 gcloud CLI。如果您建立新的工具或新增自訂工具,則必須使用用戶端程式庫或藉由直接在應用程式中使用存取權憑證的方式來授權應用程式。

為了讓自動識別服務帳戶的功能發揮效用,請為服務帳戶授予適當的身分與存取權管理角色,並將服務帳戶附加至執行個體。舉例來說,如果您為服務帳戶授予 roles/storage.objectAdmin 角色,gcloud CLI 就能自動管理及存取 Cloud Storage 物件。

同樣地,如果為服務帳戶啟用了 roles/compute.instanceAdmin.v1gcloud compute 工具就能自動管理執行個體。

後續步驟

歡迎試用

如果您未曾使用過 Google Cloud,歡迎建立帳戶,親自體驗實際使用 Compute Engine 的成效。新客戶還能獲得價值 $300 美元的免費抵免額,能用於執行、測試及部署工作負載。

免付費試用 Compute Engine