使用Python从Google Cloud函数中的附加服务帐户获取google.oauth2凭据

iovurdzv  于 2023-05-05  发布在  Python
关注(0)|答案(1)|浏览(132)

我正在编写一个Google Cloud函数,我想使用google.oauth2.service_account.with_subject()函数来模拟用户访问他们的gmail收件箱,但我无法找到一种方法来使用附加的服务帐户来获得oauth2凭据来运行它。
In the docs,建议使用google.auth.default()函数获取凭证,但这些凭证不能用于运行google.oauth2.service_account.with_subject()函数。我能想到的最好的解决方法是使用oauth2凭证来获取服务帐户json密钥文件,并使用secrets /环境变量将其加载到函数中。这看起来很混乱,尤其是当google.auth.default()展示了如何在一个行程序中完成如此相似的事情时。
考虑到我所能找到的关于我正在努力做的事情的信息是多么少,这让我认为我正在错误地处理这个问题,所以我将感谢任何不同方式处理这个问题的建议。
当我写这篇文章的时候,有人推荐了一个single post and discussion来谈论这个问题。他们似乎和我一样,但也许有一个更好的解决方案(这篇文章也没有回答我的问题,因为我特别想找一种方法从附加的服务帐户中获取oauth2凭据到云函数,而不仅仅是加载任何凭据)。
服务帐户已被授予全域授权,用户帐户属于同一域。此外,该函数被成功调用并在附加了服务帐户的情况下运行。正在使用的唯一API是gmail API,特别是'https://www.googleapis.com/auth/gmail.readonly'范围,该范围已被授予服务帐户并传递给代码中的凭据对象。
这里是一些代码上下文我想要什么,这段代码不运行.

@functions_framework.cloud_event
def process_message(cloud_event):
  """Entrypoint for Google Cloud Function."""

  SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

  # Loading the service account credentials using google.auth
  # Ideally would be google.oauth2.default(scopes=SCOPES), but that doesn't exist
  credentials, _ = google.auth.default(scopes=SCOPES)
  
  # DOES NOT WORK since this function doesn't exist for google.auth
  # and requires google.oauth2 credentials
  delegated_credentials = credentials.with_subject(user_email)

  # Fetch inbox of gmail user in our domain
  service = build('gmail', 'v1', credentials=delegated_credentials)
  results = service.users().messages().list(userId='me').execute()

  return results

我最初尝试使用这段代码:

source_credentials.refresh(requests.Request())
print("Source Credentials:", source_credentials)
target_credentials = impersonated_credentials.Credentials(
  source_credentials=source_credentials,
  target_principal='<user@domain>',
  target_scopes = SCOPES,
  lifetime=500
  )

但我会得到这个错误:google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials', '{\n "error": {\n "code": 404,\n "message": "Not found; Gaia id not found for email <user@domain>",\n "status": "NOT_FOUND"\n }\n}\n')
我试图找到更多关于这方面的信息,但在搜索错误时很难找到任何确切的命中。这就是为什么我尝试使用with_subject()函数

f0brbegy

f0brbegy1#

您创建的凭据对象类型(类)错误。相反,您必须使用service_account类。

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE_PATH,
        scopes=SCOPES)

delegated_credentials = credentials.with_subject(user_email)

相关问题