0

我正在尝试用Python向GCP进行身份验证,以便调用云函数。

我已经设置了一个具有以下角色的服务帐户在此处输入图像描述

并为其创建了一个JSON键。从“云函数”窗格中双击,我可以看到它的权限是正确的(也尝试给Admin)在此处输入图像描述

然而,身份验证似乎总是成功的

从google.oauth2导入service_account导入google.auth.transport.requestskey_path=“路径/to/key.json”scopes=['https://www.googleapis.com/auth/cloud-platform网站']credentials=服务帐户。凭证.from_service_account_file(key_path,scopes=范围)auth_request=谷歌.auth.transport.requests。请求()凭据刷新(auth_request)打印(凭证令牌)#Bearer xxxxx

但后来,无记名令牌似乎没有授予我访问API的权限,因为我得到了错误401

承载错误=“invalid_token”error_description=“无法验证访问令牌”

我多次尝试重新生成JSON密钥。这个函数本身工作得很好,因为我测试了它的公共版本,它工作得很顺利。


编辑

我还尝试使用以下代码按照文档创建JWT。仍然未能授权,从未失败过身份验证

导入json导入日期时间进口jwt导入请求#加载服务帐户密钥文件key_file_path=“路径/to/key.json”open(key_file_path)为f:service_account_info=json.load(f)#从服务帐户信息中提取必要的信息private_key=service_account_info['专用密钥']client_email=service_account_info['客户端电子邮件']#定义JWT标头和有效负载标题={“alg”:“RS256”,“典型”:“JWT”,“kid”:service_account_info['private_key_id']}now=datetime.datetime.utcnow()expiry=now+datetime.timedelta(小时=1)有效载荷={“iss”:客户端电子邮件,“sub”:客户端电子邮件,“aud”:“https://www.googleapis.com/oauth2/v4/token",“iat”:现在,“exp”:到期,“范围”:“https://www.googleapis.com/auth/cloud-platform网站"}#生成JWTjwt_token=jwt.encode(有效载荷,私有密钥,算法=“RS256”,头=头)#定义获取Google-signed ID令牌的请求token_url=“https://www.googleapis.com/oauth2/v4/token"标题={“内容类型”:“应用程序/x-www-form-urlencoded”}主体={“grant_type”:“urn:ietf:params:oauth:grant-type:jwt-bearer”,“断言”:jwt_token}#请求获取ID令牌response=requests.post(token_url,headers=headers,data=body)#打印响应(包含ID标记)如果response.status_code==200:id_token=“bearer”+response.json().get('access_token')print(“ID令牌:”,ID_Token)其他:print(“错误:”,response.json())
  • 你应该(!?)只需要2个调用程序角色(角色/cloudfunctions.invoker,角色/run.invoker). 更好|更容易使用google.auth.default()获取凭据(而不是显式引用密钥)。你的代码不完整,你在哪里对云函数提出请求?请包含对代码的最少重复。 评论 6月27日0:45
  • @DazWilkin我不确定是否只需要这两个角色,管理权限重叠,所以这不重要,但我会尝试。在这些测试之后,我不会使用Python进行身份验证,所以我更喜欢使用JSON密钥进行身份验证。根据调用我正在使用的Postman请求,我保证如果该函数没有身份验证,那么调用相同的函数也能正常工作 评论 6月27日7:39
  • @达维特姆。我已经更新了答案。请检查编辑1部分。 评论 2天前

1答案1

重置为默认值
0

根据GCP官方文件验证调用(第二代):应该使用完整的URL使此代码段正常工作。请参阅上述文档中的示例1(身份验证示例)部分。

如果401错误没有解决,请注意,要验证云函数,您需要ID_TOKEN不是访问令牌。您可以参考有关如何以编程方式生成ID_TOKEN的代码示例,如中所示生成ID令牌在上述文件中。

按照文档中的建议设置ID_TOKEN后,您应该不会遇到任何问题,即允许客户端使用HTTP端点调用云函数。

编辑1:

请参阅中等博客由编写纪尧姆·布拉基埃这提供了对诸如云功能之类的服务的安全性的清晰理解。

对于某些用例,API密钥保持了平衡的安全解决方案与“无安全性”或基本HTTP身份验证相比。谷歌云不支持这种类型的身份验证。

您可以使用一个额外的层(如云端点),并按照上面的文章创建相应的云运行端点网关,并为安全服务部署相同的云功能。

通过身份验证的用户可以使用角色/cloudfunctions.invoker。您需要将此角色授予云运行端点网关服务帐户(使用项目ID更改<PROJECT_ID>)。尝试以下命令:

gcloud项目add-iam-policy-binding<PROJECT_ID>
--role=角色/cloudfunctions.invoker--成员\
serviceAccount:endpoint-id@<PROJECT_id>.iam.gserviceaccount.com

1
  • 我也尝试过创建一个JWT,但没有任何变化,仍然是相同的错误 评论 6月27日16:22

您的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.