如果推送訂閱項目使用驗證,Pub/Sub 服務會簽署 JSON Web Token (JWT),並在推送要求的授權標頭中傳送 JWT。JWT 包含憑證附加資訊和簽章。
訂閱者可以驗證 JWT,並確認下列事項:
- 聲明內容正確無誤。
- Pub/Sub 服務已簽署聲明。
如果訂閱者使用防火牆,就無法接收推送要求。如要接收推送要求,請關閉防火牆並驗證 JWT。如果訂閱者有防火牆,您可能會收到 403 permission denied
錯誤訊息。
事前準備
JWT 格式
JWT 是由標頭、憑證附加資訊集和簽名組成的 OpenIDConnect JWT。Pub/Sub 服務會將 JWT 編碼為以英文句點分隔的 base64 字串。
舉例來說,下列授權標頭包含經過編碼的 JWT:
"Authorization" : "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjdkNjgwZDhjNzBkNDRlOTQ3MTMzY2JkNDk5ZWJjMWE2MWMzZDVh YmMiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tIiwiYXpwIjoiMTEzNzc0M jY0NDYzMDM4MzIxOTY0IiwiZW1haWwiOiJnYWUtZ2NwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvb SIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE1NTAxODU5MzUsImlhdCI6MTU1MDE4MjMzNSwia XNzIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTEzNzc0MjY0NDYzMDM4MzIxO TY0In0.QVjyqpmadTyDZmlX2u3jWd1kJ68YkdwsRZDo-QxSPbxjug4ucLBwAs2QePrcgZ6hhkvdc4UHY 4YF3fz9g7XHULNVIzX5xh02qXEH8dK6PgGndIWcZQzjSYfgO-q-R2oo2hNM5HBBsQN4ARtGK_acG-NGG WM3CQfahbEjZPAJe_B8M7HfIu_G5jOLZCw2EUcGo8BvEwGcLWB2WqEgRM0-xt5-UPzoa3-FpSPG7DHk7 z9zRUeq6eB__ldb-2o4RciJmjVwHgnYqn3VvlX9oVKEgXpNFhKuYA-mWh5o7BCwhujSMmFoBOh6mbIXF cyf5UiVqKjpqEbqPGo_AvKvIQ9VTQ"
標頭和憑證附加資訊集都是 JSON 字串。經過解碼後,會呈現以下這樣的格式:
{"alg":"RS256","kid":"7d680d8c70d44e947133cbd499ebc1a61c3d5abc","typ":"JWT"} { "aud":"https://example.com", "azp":"113774264463038321964", "email":"gae-gcp@appspot.gserviceaccount.com", "sub":"113774264463038321964", "email_verified":true, "exp":1550185935, "iat":1550182335, "iss":"https://accounts.google.com" }
傳送至推送端點的要求所附加的權杖,最多可能已過期一小時。
設定 Pub/Sub 以進行推送驗證
以下範例說明如何將推送驗證服務帳戶設為您選擇的服務帳戶,以及如何將 iam.serviceAccountTokenCreator
角色授予service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
服務代理程式。
控制台
前往「Pub/Sub Subscriptions」(Pub/Sub 訂閱項目) 頁面。
按一下「Create Subscription」 (建立訂閱項目)。
在「Subscription ID」(訂閱項目 ID) 欄位中輸入名稱。
選取主題。
將「傳送類型」設為「推送」。
輸入端點網址。
勾選「啟用驗證」。
選取服務帳戶。
確認服務代理人
service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
在專案的 IAM 資訊主頁中具有iam.serviceAccountTokenCreator
角色。如果服務帳戶尚未獲得該角色,請在 IAM 資訊主頁中按一下「授權」。選用:輸入目標對象。
點選「建立」。
gcloud
# Configure the push subscription gcloud pubsub subscriptions (create|update|modify-push-config) ${SUBSCRIPTION} \ --topic=${TOPIC} \ --push-endpoint=${PUSH_ENDPOINT_URI} \ --push-auth-service-account=${SERVICE_ACCOUNT_EMAIL} \ --push-auth-token-audience=${OPTIONAL_AUDIENCE_OVERRIDE} # Your service agent # `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the # `iam.serviceAccountTokenCreator` role. PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\ --role='roles/iam.serviceAccountTokenCreator'
為推送訂閱項目啟用驗證時,您可能會遇到 permission denied
或 not authorized
錯誤。
如要解決這個問題,請授予啟動訂閱項目建立或更新作業的主體服務帳戶 iam.serviceAccounts.actAs
權限。詳情請參閱「建立推送訂閱」一文中的「驗證」。
如果您使用已驗證的推送訂閱項目,搭配以 Identity-Aware Proxy 保護的 App Engine 應用程式,則必須提供 IAP 用戶端 ID 做為推送驗證權杖目標對象。如要在 App Engine 應用程式上啟用 IAP,請參閱「啟用 IAP」。如要尋找 IAP 用戶端 ID,請在「憑證」頁面中尋找「用戶端 ID」IAP-App-Engine-app
。
版權聲明
JWT 可用來驗證憑證附加資訊 (包括 email
和 aud
憑證附加資訊) 是否由 Google 簽署。如要進一步瞭解如何使用 Google 的 OAuth 2.0 API 進行驗證和授權作業,請參閱 OpenID Connect 一文。
有兩種機制可讓這些憑證附加資訊更具實用價值。首先,Pub/Sub 會要求發出 CreateSubscription、UpdateSubscription 或 ModifyPushConfig 呼叫的使用者或服務帳戶,皆需擁有推送授權服務帳戶的 iam.serviceAccounts.actAs
權限。例如 roles/iam.serviceAccountUser
角色。
其次,系統會嚴格控管用來簽署符記的憑證存取權。如要建立符記,Pub/Sub 必須使用不同的簽署服務帳戶身分 (即服務代理程式 service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
) 來呼叫內部 Google 服務。簽署服務帳戶必須具備 iam.serviceAccounts.getOpenIdToken
權限,或在推送授權服務帳戶 (或推送授權服務帳戶的任何上層資源,例如專案) 中擁有「服務帳戶符記建立者」角色 (roles/iam.serviceAccountTokenCreator
)。
驗證權杖
驗證 Pub/Sub 傳送至推送端點的符記時,請採取下列步驟:
- 使用簽名驗證檢查權杖完整性。
- 確認權杖中的 email 和 audience 憑證附加資訊與推送訂閱設定中設定的值相符。
以下範例說明如何驗證向未受 Identity-Aware Proxy 保護的 App Engine 應用程式提出的推送請求。如果您的 App Engine 應用程式受到 IAP 保護,含有 IAP JWT 的 HTTP 要求標頭為 x-goog-iap-jwt-assertion
,且必須相應驗證。
通訊協定
請求:
GET https://oauth2.googleapis.com/tokeninfo?id_token={BEARER_TOKEN}
回應:
200 OK
{ "alg": "RS256", "aud": "example.com", "azp": "104176025330667568672", "email": "{SERVICE_ACCOUNT_NAME}@{YOUR_PROJECT_NAME}.iam.gserviceaccount.com", "email_verified": "true", "exp": "1555463097", "iat": "1555459497", "iss": "https://accounts.google.com", "kid": "3782d3f0bc89008d9d2c01730f765cfb19d3b70e", "sub": "104176025330667568672", "typ": "JWT" }
C#
在嘗試這個範例之前,請先按照快速入門:使用用戶端程式庫中的 C# 設定操作說明進行操作。詳情請參閱 Pub/Sub C# API 參考說明文件。
Go
Java
Node.js
Python
Ruby
如要瞭解上述程式碼範例中使用的環境變數 PUBSUB_VERIFICATION_TOKEN
,請參閱「寫入及回應 Pub/Sub 訊息」。
如需驗證不記名 JWT 的其他範例,請參閱網站專用的 Google 登入指南。如要進一步瞭解 OpenID 符記,請參閱 OpenID Connect 指南,包括有助於驗證 JWT 的用戶端程式庫清單。
從其他 Google Cloud 服務驗證
Cloud Run 和 App Engine 函式會驗證 Pub/Sub 產生的權杖,藉此驗證來自 Pub/Sub 的 HTTP 呼叫。您唯一需要進行的設定,就是將必要的 IAM 角色授予呼叫端帳戶。
如要瞭解這些服務的不同用途,請參閱下列指南和教學課程:
Cloud Run
- 透過 Pub/Sub 推送觸發:
推送授權服務帳戶必須具備
roles/run.invoker
角色,並繫結至 Cloud Run 服務,才能叫用對應的 Cloud Run 服務 - 搭配使用 Pub/Sub 與 Cloud Run 教學課程
App Engine
Cloud Run 函式
- HTTP 觸發條件:
如要使用 Pub/Sub 推送要求做為函式的 HTTP 觸發條件,推送授權服務帳戶必須具備
roles/cloudfunctions.invoker
角色,才能叫用函式。 - Google Cloud Pub/Sub 觸發條件: 如果您使用 Pub/Sub 觸發條件叫用函式,系統會自動設定 IAM 角色和權限