在 python 中,我尝试通过服务帐户调用 GMail API委派全域权限 https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests, without using SERVICE_ACCOUNT_FILE
.
我的目标是避免制造秘密Key
对于服务帐户。相反,我给了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] /cdn-cgi/l/email-protection' doesn't work here :'(
)
service = googleapiclient.discovery.build('gmail', 'v1', credentials=Credentials(tk.access_token))
response = service.users().messages().insert(userId='[email protected] /cdn-cgi/l/email-protection', body=body).execute()
问题是,在 Google Admin 中向服务帐户授予权限后my.domain
,我收到以下错误:
{'message': '前置条件检查失败。', 'domain': '全局', 'reason': 'failedPrecondition'}
我怀疑我缺少的是subject
,即管理员的电子邮件地址my.domain
.
我知道我可以提供subject
通过构建credentials
不同的是:
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] /cdn-cgi/l/email-protection'). # <- I need this
service = googleapiclient.discovery.build('gmail', 'v1', credentials=delegated_credentials)
但这需要创建一个密钥,我想避免这种情况。
有没有办法传递上面第一个代码示例中的主题?