google-cloud-platform - Google Cloud Build 获取身份令牌
问题描述
在我的场景中,我想在 Google Cloud Build 期间触发基于 HTTP 端点的 Google Cloud Function。HTTP 请求是使用带有 python:3.7-slim 容器的步骤完成的。
REGION = 'us-central1'
PROJECT_ID = 'name-of-project'
RECEIVING_FUNCTION = 'my-cloud-function'
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'
metadata_server_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_full_url = metadata_server_url + function_url
token_headers = {'Metadata-Flavor': 'Google'}
token_response = requests.get(token_full_url, headers=token_headers)
jwt = token_response.text
print(jwt)
r = requests.post(url=function_url, headers=function_headers, json=payload)
令人惊讶的是,代码失败是因为jwt
是Not Found
(根据print
声明)。我已经通过硬编码有效的身份令牌测试了代码和 IAM 设置,并且还在同一项目内的测试 VM 上测试了完全相同的获取机制。问题似乎是获取一些元数据在云构建中不起作用。
我错过了什么吗?感谢您的任何帮助!
解决方案
解决方案是使用新的 IAM api 在具有访问令牌的服务帐户上生成 ID_TOKEN,如果请求者(生成访问令牌的人)在服务帐户(或广泛使用该项目)。
第一个示例使用直接 API 调用
- name: gcr.io/cloud-builders/gcloud
entrypoint: "bash"
args:
- "-c"
- |
curl -X POST -H "content-type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-d '{"audience": "YOUR AUDIENCE"}' \
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/YOUR SERVICE ACCOUNT:generateIdToken"
# Use Cloud Build Service Account
# service_account_email=$(gcloud config get-value account)
这里是 Python 代码版本
- name: python:3.7
entrypoint: "bash"
args:
- "-c"
- |
pip3 install google-auth requests
python3 extract-token.py
并extract-token.py
包含以下代码
REGION = 'us-central1'
PROJECT_ID = 'name-of-project'
RECEIVING_FUNCTION = 'my-cloud-function'
function_url = f'https://{REGION}-{PROJECT_ID}.cloudfunctions.net/{RECEIVING_FUNCTION}'
import google.auth
credentials, project_id = google.auth.default(scopes='https://www.googleapis.com/auth/cloud-platform')
# To use the Cloud Build service account email
service_account_email = credentials.service_account_email
#service_account_email = "YOUR OWN SERVICE ACCOUNT"
metadata_server_url = f'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{service_account_email}:generateIdToken'
token_headers = {'content-type': 'application/json'}
from google.auth.transport.requests import AuthorizedSession
authed_session = AuthorizedSession(credentials)
import json
body = json.dumps({'audience': function_url})
token_response = authed_session.request('POST',metadata_server_url, data=body, headers=token_headers)
jwt = token_response.json()
print(jwt['token'])
如果您需要更多详细信息,请不要犹豫。
我想我会在 Medium 上写一篇关于这个的文章,如果你想要我的名字,请告诉我
推荐阅读
- kubernetes - HTTPS 请求重定向到 HTTP
- android - 如何使用处理程序创建计时器
- sql - Node js 向 SQL Server 发出请求,返回结果
- microsoft-graph-api - 在 Microsoft Graph 中获取附加消息的附件
- javascript - Javascript 函数在 Google 检查功能中触发,但并非如此
- python - 如何使用网格而不是包使我的 python 滚动条可滚动和画布自动调整大小
- linux - 在 bash case 语句中出现语法错误
- excel - 增加范围
- xslt - 如何比较同一组的兄弟姐妹?
- javascript - 我正在制作基于文本的 RPG,您可以在每个屏幕上说是或否,我需要帮助删除事件监听器