簡體   English   中英

如何使用 API 雲網關 Function 傳遞的服務帳戶的 884645589888 在雲中初始化 Google BigQuery 客戶端 Function

[英]How to initialize a Google BigQuery Client within a Cloud Function using the JWT of a service account passed by API Gateway to the Cloud Function

目標:
我已經設置了一個谷歌 API 網關。 API 的后端是雲 function(用 Python 編寫)。 雲 function 應該從 Google BigQuery (BQ) 查詢數據。 為此,我想創建一個 BQ 客戶端 ( google.cloud.bigquery.Client() )。 API 應由使用不同服務帳戶的不同應用程序訪問。 服務帳戶僅有權訪問我的項目中的特定數據集。 因此,服務帳戶/應用程序應該只能查詢他們有權查詢的數據集。 因此,雲function內的BQ Client應該初始化為向API發送請求的服務賬號。

我嘗試了什么:
API 使用以下 OpenAPI 定義進行保護,因此需要由服務帳戶 SA-EMAIL 簽名的 884645589888 才能向那里發送請求:

securityDefinitions:
  sec-def1:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "SA-EMAIL"
    x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA-EMAIL"
    x-google-audiences: "SERVICE"

對於使用我的雲 function 的路徑,我使用以下后端配置:

x-google-backend:
  address: https://PROJECT-ID.cloudfunctions.net/CLOUD-FUNCTION
  path_translation: CONSTANT_ADDRESS 

因此,在雲 function 本身中,我從 API 網關獲得轉發的 JWT 作為X-Forwarded-Authorization以及已經驗證的 base64url 編碼的 JWT 有效負載作為X-Apigateway-Api-Userinfo
我嘗試使用X-Forwarded-Authorization中的 JWT 來獲取憑據:

bearer_token = request.headers.get('X-Forwarded-Authorization')
token = bearer_token.split(" ")[1]
cred = google.auth.credentials.Credentials(token)

起初,這似乎有效,因為cred.valid返回True ,但是當嘗試使用google.cloud.bigquery.Client(credentials=cred)創建客戶端時,它在日志中返回以下錯誤:

google.auth.exceptions.RefreshError: The credentials do not contain 
the necessary fields need to refresh the access token. You must 
specify refresh_token, token_uri, client_id, and client_secret.

我對 auth/oauth 沒有太多經驗,但我認為我沒有必要的令牌/屬性,錯誤是說在我的雲 function 中缺少可用的。另外,我不確定為什么會有RefreshError ,因為我不想刷新令牌(並且不想明確地這樣做)並再次使用它(可能是不好的做法?)。

問題:
是否有可能以我嘗試過的方式或任何其他方式實現我的目標?

您的目標是獲取調用 API 網關的憑證,並在您的 Cloud Functions 中重用它來調用 BigQuery。

可悲的是,你不能。 為什么? 因為 API 網關阻止您實現這一目標(出於安全原因,這是一個好消息)。 JWT 令牌已正確轉發到您的 Cloud Functions,但簽名部分已被刪除(您僅收到 header 和 JWT 令牌的主體)。

安全驗證已由 API 網關完成,您必須依賴該身份驗證。


解決辦法是什么?

我的解決方案如下:在您收到的截斷 JWT 中,您可以獲得正文和服務帳戶 email。從那里,您可以使用 Cloud Functions 服務帳戶來模擬您收到的服務帳戶 email。

這樣,Cloud Functions 服務賬戶只需要模擬這些服務賬戶的權限,而您保留原始服務賬戶上提供的權限。

我沒有看到其他解決方案來解決您的問題。

您從 API 網關收到的 JWT 不是 OAuth 訪問令牌。 因此,JWT 有效負載部分不是可用於 BigQuery 客戶端授權的憑據。

正如@guillaume blaquiere指出的那樣,有效負載包含身份的 email 地址。 如果身份是服務帳戶,您可以實施該身份的模擬。 如果您在 API 網關上使用多個身份,這可能是一個很好的解決方案。 如果身份是用戶帳戶,則您需要實施全域委派。

我建議只使用分配給 Cloud Function 的服務帳戶,並分配適當的角色來初始化 BigQuery 客戶端。 如果 API 網關提供訪問您的雲 Function 的授權,則不需要額外的模擬層。

另一種選擇是將匹配的服務帳戶 JSON 密鑰文件存儲在 Secret Manager 中,並在需要創建 BigQuery Client 時拉取它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM