![](/img/trans.png)
[英]How to create signed Google Cloud Storage URLs in Cloud Function using Cloud Function service account?
[英]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.