python-3.x - 在本地机器上对 GCP 上的服务到服务进行身份验证失败
问题描述
我正在尝试进行身份验证,但是 python3 中的请求库不允许我获取令牌。使用以下代码示例:https ://cloud.google.com/run/docs/authenticating/service-to-service#python
# Requests is already installed, no need to add it to requirements.txt
import requests
receiving_service_url = "https://myproject....run.app"
# Set up metadata server request
# See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_request_url = metadata_server_token_url + receiving_service_url
token_request_headers = {'Metadata-Flavor': 'Google'}
# Fetch the token
### CRASHES HERE ###
token_response = requests.get(token_request_url, headers=token_request_headers) ###
### CRASHES HERE ###
jwt = token_response.content.decode("utf-8")
# Provide the token in the request to the receiving service
receiving_service_headers = {'Authorization': f'bearer {jwt}'}
service_response = requests.get(receiving_service_url, headers=receiving_service_headers)
print(service_response.content)
如果我使用 iPython 在 gcp 的控制台中运行相同的代码,它可以获取令牌。我可以在本地机器上使用它,例如 CURL。
错误:
token_response = requests.get(token_request_url, headers=token_request_headers)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='metadata', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/identity?audience=https://myproject....run.app (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f87f0573370>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
INFO:werkzeug:127.0.0.1 - - [08/Oct/2020 23:54:14] "GET / HTTP/1.1" 200 -
为什么在本地机器上运行时无法建立连接?
解决方案
如果您的代码基于元数据服务器,则它只能在 Google Cloud 上运行。我昨天回答了这个问题,我想,你可以从中得到启发。
您可以使用 IAM REST API 来生成 IDToken,而不是使用元数据服务器。像这样,它可以在本地和云端运行。
代码有点长,不知道IAM API是否和元数据服务器一样高效。
如果您需要详细信息和解释,请随时发表评论!
推荐阅读
- docker - 带有 Docker 的 nodejs 中的本地 kubernetes Hello World
- kubernetes - Kubernetes LoadBalancer 服务在向集群添加新节点后停止响应
- java - 如何设置 Spring + Hibernate 依赖注入的代码?
- django - 如何在 django 信号 post_save 中使用 update_fields
- eclipselink - RCP e4 EclipseLink 错误:没有名为 EntityManager 的持久性提供程序
- c++ - 编译器如何知道 C++ constexpr 计算不会触发未定义的行为?
- javascript - 使用纯 javascript 打开本地服务器文件
- r - 有没有更好的方法为列表中的每个值执行 group_by ?
- linux - 在 Linux 中删除文件名的中间部分
- python - 无法从“util”导入名称“box_2d_to_points”