服務之間的驗證
除了驗證使用者要求,您可能還需要驗證向 API 提出要求的服務 (非人類使用者)。本頁面說明如何使用服務帳戶為使用者或服務提供驗證。
總覽
為了識別傳送要求至您 API 的服務,需要使用服務帳戶。呼叫服務會使用服務帳戶的私密金鑰來簽署安全的 JSON Web Token (JWT),並將要求中的已簽署 JWT 傳送到您的 API。
如要在 API 和呼叫服務中實作服務帳戶驗證,請按照下列步驟操作:
- 建立呼叫服務要使用的服務帳戶與金鑰。
- 在 API Gateway 服務的 API 設定中新增驗證支援。
將程式碼新增到呼叫服務,如此就會:
- 建立 JWT 並以服務帳戶私密金鑰簽署。
- 在要求中將已簽署的 JWT 傳送至 API。
API Gateway 會先驗證 JWT 中的憑證附加資訊是否符合 API 設定中的設定,再將要求轉送至您的 API。API Gateway 不會檢查該服務帳戶已授予的 Cloud Identity 權限。
必要條件
本頁假設您已具備以下條件:
使用金鑰建立服務帳戶
您會需要一個服務帳戶,這個服務帳戶需擁有呼叫服務用來簽署 JWT 的私密金鑰檔案。如果您有多個服務會向您的 API 發送要求,則可建立一個服務帳戶來代表所有的呼叫服務。如果您需要區別不同服務 (例如各服務具有的權限可能各不相同),就可以為每個呼叫服務建立服務帳戶和金鑰。
本節會示範如何使用 Google Cloud 主控台和 gcloud
指令列工具建立服務帳戶和私密金鑰檔案,並將服務帳戶憑證建立者角色指派給服務帳戶。如要瞭解如何使用 API 進行這項工作,請參閱「建立和管理服務帳戶」。
如何使用金鑰建立服務帳戶:
Google Cloud 控制台
建立服務帳戶:
前往 Google Cloud 控制台的「Create service account」(建立服務帳戶) 。
選取專案。
在「Service account name」(服務帳戶名稱) 欄位中輸入名稱。Google Cloud 控制台會根據這個名稱填入「Service account ID」欄位。
選用:在「服務帳戶說明」欄位中輸入說明。
按一下 [建立]。
按一下「請選擇角色」欄位。
在「All roles」(所有角色) 下方,依序選取「Service Accounts」(服務帳戶) >「Service Account Token Creator」(服務帳戶憑證建立者)。
按一下「繼續」。
按一下「Done」(完成),即完成建立服務帳戶。
請勿關閉瀏覽器視窗。您將在下一個程序中使用此值。
建立服務帳戶金鑰:
- 在 Google Cloud 控制台中,按一下您建立的服務帳戶電子郵件地址。
- 點選「金鑰」。
- 依序點選「新增金鑰」和「建立新的金鑰」。
- 按一下「建立」,JSON 金鑰檔案會下載至您的電腦。
- 按一下 [關閉]。
gcloud
您可以使用本機電腦上的 Google Cloud CLI 或在 Cloud Shell 內執行下列指令。
設定
gcloud
的預設帳戶。如果您有多個帳戶,請確認所選擇的帳戶位於您要使用的 Google Cloud 專案中。gcloud auth login
顯示 Google Cloud 專案的專案 ID。
gcloud projects list
設定預設專案。將
PROJECT_ID
替換為您要使用的 Google Cloud 專案 ID。gcloud config set project PROJECT_ID
建立服務帳戶。將
SA_NAME
和SA_DISPLAY_NAME
替換為您要使用的名稱和顯示名稱。gcloud iam service-accounts create SA_NAME \ --display-name "SA_DISPLAY_NAME"
顯示剛剛建立的服務帳戶的電子郵件地址。
gcloud iam service-accounts list
新增服務帳戶憑證建立者角色。將
SA_EMAIL_ADDRESS
替換成服務帳戶的電子郵件地址。gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:SA_EMAIL_ADDRESS \ --role roles/iam.serviceAccountTokenCreator
在目前的工作目錄中建立服務帳戶金鑰檔案。將
FILE_NAME
替換為您要用於金鑰檔案的名稱。根據預設,gcloud
指令會建立一個 JSON 檔案。gcloud iam service-accounts keys create FILE_NAME.json \ --iam-account SA_EMAIL_ADDRESS
如要進一步瞭解上述指令,請參閱 gcloud
參考資料。
如需私密金鑰保護措施的相關資訊,請參閱管理憑證的最佳做法。
設定 API 以支援驗證
為閘道建立 API 設定時,請指定閘道用於與其他服務互動的服務帳戶。如要為呼叫閘道器的服務啟用服務帳戶驗證,請修改 API 設定中的 安全性需求物件和 安全性定義物件。按照下列步驟操作,API Gateway 就能驗證呼叫服務使用的已簽署 JWT 中的宣告。
在 API 設定中將服務帳戶新增為發行者。
securityDefinitions: DEFINITION_NAME: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "SA_EMAIL_ADDRESS" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA_EMAIL_ADDRESS"
- 將
DEFINITION_NAME
替換成可用來識別此安全性定義的字串。建議將其替換成服務帳戶名稱或是能辨別呼叫服務的名稱。 - 將
SA_EMAIL_ADDRESS
替換成服務帳戶的電子郵件地址。 - 您可以在 API 設定中定義多項安全定義,但每項定義必須要有不同的
x-google-issuer
。如果您為每個呼叫服務建立了個別的服務帳戶,則可以再為每個服務帳戶建立安全性定義,例如:
securityDefinitions: service-1: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-1@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-1@example-project-12345.iam.gserviceaccount.com" service-2: authorizationUrl: "" flow: "implicit" type: "oauth2" x-google-issuer: "service-2@example-project-12345.iam.gserviceaccount.com" x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-2@example-project-12345.iam.gserviceaccount.com"
- 將
也可以將
x-google-audiences
新增至securityDefinitions
區段。如果您沒有新增x-google-audiences
,API Gateway 會要求 JWT 中的"aud"
(目標對象) 憑證附加資訊格式為https://SERVICE_NAME
,其中 SERVICE_NAME 是 API Gateway 服務名稱,您已在 OpenAPI 文件的host
欄位中設定。在檔案頂層 (非縮排或巢狀結構) 新增一個
security
區段,並套用至整個 API,或是在方法層中套用至特定方法。如果您在 API 層級和方法層級使用security
區段,方法層級的設定就會覆寫 API 層級的設定。security: - DEFINITION_NAME: []
- 將
DEFINITION_NAME
替換成您在securityDefinitions
區段中使用的名稱。 如果您在
securityDefinitions
區段中有多個定義,請將其新增至security
區段,例如:security: - service-1: [] - service-2: []
- 將
部署已更新的 API 設定。
在 API Gateway 將要求轉送至您的 API 之前,API Gateway 會驗證以下項目:
- 使用公開金鑰的 JWT 簽署,位於 API 設定中
x-google-jwks_uri
欄位指定的 URI。 - JWT 中的
"iss"
(發行者) 憑證附加資訊與x-google-issuer
欄位指定的值是否相符。 - JWT 中的
"aud"
(目標對象) 憑證附加資訊是否含有您的 API Gateway 服務名稱,或是否與x-google-audiences
欄位指定的其中一個值相符。 - 使用
"exp"
(到期時間) 憑證附加資訊,確認憑證並未過期。
如要進一步瞭解 x-google-issuer
、x-google-jwks_uri
和 x-google-audiences
,請參閱 OpenAPI 擴充功能。
向 API Gateway API 發出經過驗證的要求
為了發出經過驗證的要求,呼叫服務會傳送您在 API 設定中指定的服務帳戶簽署的 JWT。呼叫服務必須:
- 建立一個 JWT,並以服務帳戶私密金鑰簽署。
- 在要求中將簽署的 JWT 傳送至 API。
以下範例程式碼示範選定語言的這項程序。如要以其他語言提出已驗證的要求,請參閱 jwt.io 的支援程式庫清單。
- 在呼叫服務中,新增以下函式,並將以下參數傳送給函式:
Java saKeyfile
:服務帳戶私密金鑰檔案的完整路徑。saEmail
:服務帳戶的電子郵件地址。-
audience
:如果已在 API 設定中新增x-google-audiences
欄位,請將audience
設為您指定給x-google-audiences
的其中一個值。或是將audience
設為https://SERVICE_NAME
,其中SERVICE_NAME
是您的 API Gateway 服務名稱。 expiryLength
:JWT 的到期時間,以秒為單位。
Python sa_keyfile
:服務帳戶私密金鑰檔案的完整路徑。sa_email
:服務帳戶的電子郵件地址。-
audience
:如果已在 API 設定中新增x-google-audiences
欄位,請將audience
設為您指定給x-google-audiences
的其中一個值。或是將audience
設為https://SERVICE_NAME
,其中SERVICE_NAME
是您的 API Gateway 服務名稱。 expiry_length
:JWT 的到期時間,以秒為單位。
Go saKeyfile
:服務帳戶私密金鑰檔案的完整路徑。saEmail
:服務帳戶的電子郵件地址。-
audience
:如果已在 API 設定中新增x-google-audiences
欄位,請將audience
設為您指定給x-google-audiences
的其中一個值。或是將audience
設為https://SERVICE_NAME
,其中SERVICE_NAME
是您的 API Gateway 服務名稱。 expiryLength
:JWT 的到期時間,以秒為單位。
此函式會建立一個 JWT,並使用私密金鑰檔案來簽署 JWT,然後將已簽署的 JWT 傳回。
Java Python Go - 在呼叫服務中,新增下列函式,以在要求中使用
Authorization: Bearer
標頭傳送已簽署的 JWT 給 API:Java Python Go
當您使用 JWT 傳送一項要求時,基於安全考量,建議您將驗證憑證放入 Authorization: Bearer
標頭之中。例如:
curl --request POST \ --header "Authorization: Bearer ${TOKEN}" \ "${GATEWAY_URL}/echo"
其中 GATEWAY_URL
和 TOKEN
分別是內含您部署的網關網址和認證權杖的環境變數。
在 API 中接收經過驗證的結果
API Gateway 通常會轉發所有收到的標頭。不過,如果後端位址是由 API 設定中的 x-google-backend
指定,則會覆寫原始 Authorization
標頭。
API Gateway 會將 X-Apigateway-Api-Userinfo
中的驗證結果傳送至後端 API。建議您改用這個標頭,而不要使用原始的 Authorization
標頭。此標頭是由 base64url
所編碼,並包含 JWT 酬載。