带有Google服务帐户主题的Generate_Access_Token() [英] generate_access_token() with subject for Google service account

查看:24
本文介绍了带有Google服务帐户主题的Generate_Access_Token()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python中,我尝试使用Delegated domain-wide authority而不是使用SERVICE_ACCOUNT_FILE通过服务帐户调用Gmail API。

我的目标是避免为服务帐户创建密码。相反,我将Service Account Token Creator角色分配给了进程所有者(本地开发中的我,生产中的App Engine服务帐户)。

在下面的代码中,我成功地获取并使用了服务帐户的访问令牌,但没有任何SERVICE_ACCOUNT_FILE

from google.cloud.iam_credentials_v1 import IAMCredentialsClient
from google.oauth2.credentials import Credentials
import googleapiclient.discovery

tk = IAMCredentialsClient().generate_access_token(
    name=f'projects/-/serviceAccounts/{service_id}',
    scope=['https://www.googleapis.com/auth/gmail.insert'],
    # subject='admin@my.domain' doesn't work here :'(
)
service = googleapiclient.discovery.build('gmail', 'v1', credentials=Credentials(tk.access_token))
response = service.users().messages().insert(userId='user@my.domain', body=body).execute()

问题是,在my.domain的Google Admin中向服务帐户授予权限后,我收到以下错误:

{‘Message’:‘前置条件检查失败。’,‘DOMAIN’:‘GLOBAL’,‘REASON’:‘FailedPredition’}

我怀疑我遗漏的是subject,即my.domain管理员的电子邮件。

我知道我可以通过以不同的方式构造credentials来提供subject

from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(key_file, scopes=scopes)
delegated_credentials = credentials.with_subject('admin@my.domain'). # <- I need this
service = googleapiclient.discovery.build('gmail', 'v1', credentials=delegated_credentials)

但这需要创建密钥,这是我希望避免的。

是否有方法传递上面第一个代码示例中的主题?

推荐答案

AFAIK这是不可能的

如果在这方面被证明是错误的,我会很高兴的!

我将此作为免责声明,因为您是对的,它并没有明确否认这种可能性。通常不要求文档明确表达您可以而不是做的所有事情,尽管我确实看到这里可能会产生混淆,因此将反馈发送到文档页面可能是值得的。

说明内容

准备进行授权的API调用

从API控制台获取客户端邮箱地址和私钥后...

source

它在任何地方都没有显示&这是一个可选步骤。在其他地方也是如此,如Directory API instructions on domain-wide delegationReports API

建议不要使用密钥

以下内容摘自您链接的文章:

只有在没有可行的替代方案时才使用服务帐户密钥

服务帐户密钥允许应用程序作为服务进行身份验证 帐户,类似于用户使用用户名进行身份验证的方式 密码。

source

当您附加服务帐户时,例如附加到App Engine实例,该实例类似于用户,而服务帐户是其用户帐户。它充当实例的一种身份。有关其他StackOverflow thread的更多信息。

因此,服务帐户充当另一个帐户的唯一方式是使用密钥。同样,用户充当-如果它是服务帐户-的唯一方式是使用密钥。因此,如果您尝试启用全域委派,前提是您希望让服务帐户作为-如果是其他帐户,拥有密钥是必不可少的,无论该服务帐户是否附加到App Engine实例。

当然,没有明确提到没有键无法实现这一点。虽然它没有提到您也可以。从我运行的测试来看,我遇到了与您相似的结果,所以似乎您就是做不到。正如免责声明中提到的那样,我很高兴被证明是错误的,但我怀疑这是由于漏洞,而不是故意的行为。

您还没有提到为什么需要域范围的授权委派,所以您可能希望评估一下您是否真的需要它。通常所需要的只是OAuth流,在该流中,应用程序代表用户,而不是如果是用户的话。

参考资料

这篇关于带有Google服务帐户主题的Generate_Access_Token()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆