我正试图生成一个id_token,使用以下代码对谷歌云函数进行身份验证调用,我从这里得到了:
# IAP audience is the ClientID of IAP-App-Engine-app in
# the API->credentials page
# Cloud Function and Cloud Run need the base URL of the service
audience = 'my_cloud_function_url'
# #1 Get the default credential to generate the access token
credentials, project_id = google.auth.default()
# #2 To use the current service account email
service_account_email = credentials.service_account_email
# Don't work with user account, so define manually the email
# service_account_email = 'MY SERVICE ACCOUNT EMAIL'
# #3 prepare the call the the service account credentials API
sa_credentials_url = f'https://iamcredentials.googleapis.com/'
f'v1/projects/-/serviceAccounts/'
f'{service_account_email}:generateIdToken'
headers = {'Content-Type': 'application/json'}
# Create an AuthorizedSession that includes
# automatically the access_token based on your credentials
authed_session = AuthorizedSession(credentials)
# Define the audience in the request body
# add the parameter "'includeEmail':true" for IAP access
body = json.dumps({'audience': audience})
# Make the call
token_response = authed_session.request('POST',sa_credentials_url,
data=body, headers=headers)
jwt = token_response.json()
id_token = jwt['token']
我没有在谷歌云环境中运行它,所以我将Google_APPLICATION_CREDENTIALS设置为控制台中生成的服务帐户的json文件。我已要求我的网络经理授权[]中的服务帐户https://www.googleapis.com/auth/cloud-platform']范围。
当我运行脚本时,我得到以下错误:
{'error': {'code': 403, 'message': 'The caller does not have permission', 'status': 'PERMISSION_DENIED'}}
我想这个错误与没有实习生访问这个服务帐户有关,但我不确定,有人能帮我吗?
编辑:
正如@guillaume blaquiere在评论中所说,您可以在不调用服务帐户凭据API的情况下获得id_token,我可以获得id_taken,但无法使用该id_token调用我的服务帐户
import google.oauth2.id_token
import google.auth.transport.requests
request = google.auth.transport.requests.Request()
audience = 'my_cloud_function_url'
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
headers = {'Authorization': f'bearer {id_token}'}
service_response = requests.get(audience, headers=headers)
有人知道为什么id_token无效吗?
您不需要调用Service Account Credential API,您可以使用fetch_id_token
方法(但您必须知道它的存在!它不是很有名,也没有文档!(
import google.oauth2.id_token
import google.auth.transport.requests
request = google.auth.transport.requests.Request()
audience = 'my_cloud_function_url'
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
库使用您在GOOGLE_APPLICATION_CREDENTIALS
env vars中设置的默认凭据。因此,使用这个python lib获取ID令牌非常方便!
403错误The caller does not have permission
意味着您的云功能的运行服务帐户没有调用该功能所需的角色。您能否转到IAM,检查您的服务帐户是否具有云功能调用程序角色?如果服务帐户没有权限,请按照以下步骤操作:
- 检查您的服务帐户在IAM中的角色,查找角色列,并验证它是否不具有上述角色
- 要添加权限,请将鼠标悬停在您的服务帐户上,然后单击右侧名为
Inheritance
的列中的编辑 - 选择角色云功能>云函数调用程序
- 单击保存