问题描述
在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='[email protected]' doesn't work here :'(
)
service = googleapiclient.discovery.build('gmail', 'v1', credentials=Credentials(tk.access_token))
response = service.users().messages().insert(userId='[email protected]', body=body).execute()
问题是,在my.domain
的Google Admin中向服务帐户授予权限后,我收到以下错误:
我怀疑我遗漏的是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('[email protected]'). # <- I need this
service = googleapiclient.discovery.build('gmail', 'v1', credentials=delegated_credentials)
但这需要创建密钥,这是我希望避免的。
是否有方法传递上面第一个代码示例中的主题?
推荐答案
AFAIK这是不可能的
我将此作为免责声明,因为您是对的,它并没有明确否认这种可能性。通常不要求文档明确表达您可以而不是做的所有事情,尽管我确实看到这里可能会产生混淆,因此将反馈发送到文档页面可能是值得的。
说明内容
它在任何地方都没有显示&这是一个可选步骤。在其他地方也是如此,如Directory API instructions on domain-wide delegation或Reports API建议不要使用密钥
以下内容摘自您链接的文章:
当您附加服务帐户时,例如附加到App Engine实例,该实例类似于用户,而服务帐户是其用户帐户。它充当实例的一种身份。有关其他StackOverflow thread的更多信息。
因此,服务帐户充当另一个帐户的唯一方式是使用密钥。同样,用户充当-如果它是服务帐户-的唯一方式是使用密钥。因此,如果您尝试启用全域委派,前提是您希望让服务帐户作为-如果是其他帐户,拥有密钥是必不可少的,无论该服务帐户是否附加到App Engine实例。
当然,没有明确提到没有键无法实现这一点。虽然它没有提到您也可以。从我运行的测试来看,我遇到了与您相似的结果,所以似乎您就是做不到。正如免责声明中提到的那样,我很高兴被证明是错误的,但我怀疑这是由于漏洞,而不是故意的行为。
您还没有提到为什么需要域范围的授权委派,所以您可能希望评估一下您是否真的需要它。通常所需要的只是OAuth流,在该流中,应用程序代表用户,而不是如果是用户的话。
参考资料
- Access to Google APIs with Service Accounts
- How to Authenticate Service Accounts
- Directory API instructions on domain-wide delegation
- Reports API instructions on domain-wide delegation
- "How to assign multiple service accounts to cloud functions" (you can't)。
这篇关于带有Google服务帐户主题的Generate_Access_Token()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!