如果推送訂閱項目使用驗證,Pub/Sub 服務會簽署 JWT,並在推送要求的授權標頭中傳送 JWT。JWT 包含憑證附加資訊和簽章。
訂閱者可以驗證 JWT,並驗證下列項目:
- 聲明內容正確。
- Pub/Sub 服務已簽署權利要求。
如果訂閱者使用防火牆,就無法收到推播要求。如要接收推播要求,您必須關閉防火牆並驗證 JWT。
事前準備
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 訂閱項目」頁面。
按一下「Create Subscription」 (建立訂閱項目)。
在「Subscription ID」(訂閱項目 ID) 欄位中輸入名稱。
選取主題。
選取「Push」做為「Delivery type」。
輸入端點網址。
勾選「啟用驗證」。
選取服務帳戶。
請確認服務代理人
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,請在「Credentials」頁面中尋找「IAP-App-Engine-app
Client ID」(用戶端 ID)。
版權聲明
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 訊息」。
您可以在網站專用的 Google 登入指南中找到有關驗證不記名 JWT 的其他範例。OpenID Connect 指南提供了更廣泛的 OpenID 符記總覽,包括可協助驗證 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 角色和權限