我有一个使用 IMAP 从 Google 邮箱获取电子邮件的程序。它目前在 IMAP 协议中使用用户名/密码(“PLAIN”)身份验证。我想将其更改为支持 XOAUTH2 身份验证。该程序是用 .NET 编写的,在 Windows 上作为服务运行,因此没有机会进行通常与 OAuth2 关联的授权同意请求。
在我看来,正确的程序应该是:
- 在 Google 的电子邮件地址帐户上创建一个“项目”,其唯一目的是获取邮件。
- 在该项目上创建一个“服务帐户”(我相信它应该能够实现无人值守访问)
- 上传证书,以便 Google 可以使用其公钥来验证访问令牌请求,该请求由客户端 Windows 服务使用私钥进行签名
- 使用 ServiceAccountCredential 及其 Initializer 类(Google.Apis.Auth NUGet 包的一部分)获取访问令牌
- 在 IMAP 协议设置期间传递访问令牌。
我似乎面临两种选择:第一,当我在构建 ServiceAccountCredential 时省略设置用户时,我可以获得访问令牌,但在 IMAP 中使用时,我会得到授权失败。第二,当我提供电子邮件地址作为用户时,我会在尝试获取访问令牌时收到以下错误:
Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested
我在这里假设错误消息中提到的“客户端”指的是 Google 项目,尽管我可能错了,但它可能指的是服务帐户。无论如何,请求的范围是https://mail.google.com/
在 Google 项目的设置中,我可以看到(“已启用的 API 和服务”),我可以在其中为项目启用某些 API(已启用 GMail API)。
我还可以看到,如果我进入“OAuth 同意屏幕”,我可以在其中为所选 API 授权特定范围,特别是我可以在其中启用https://mail.google.com/范围。然而,这里的整个目标是不设置任何同意屏幕(并且在任何情况下启用https://mail.google.com/这里的范围没有帮助)。
我不想访问任何其他邮箱,所以我认为我不需要服务帐户上的“全域委派”。此外,这只是一个个人邮件帐户,不涉及 Google 域。
看来我不知道如何授权服务帐户(或项目)的范围,尽管错误消息的“这个或那个”性质可能误导了我。或者也许我完全误解了这一点...
有什么建议吗?
答案1
服务账户作为其自己的实体存在 - 它们可以访问项目的资源,但无法访问您的个人帐户,因为它是一个单独的帐户。只有在属于 Google Workspace 域的项目中,才有可能允许服务帐户模拟同一域的用户(“全域委派”);这不适用于个人 Gmail 帐户。
因此,为了访问你的个人账户邮箱,该应用程序必须至少浏览一次 OAuth 同意屏幕并获取刷新令牌。获得刷新令牌(长期有效)后,应用可以存储它并在需要时获取访问令牌(使用非交互式“刷新令牌授予”)。
通常,您可以通过将应用分成两部分来实现此目的:一个获取刷新令牌(并将其存储在某处)的交互式程序和一个仅使用已存储在其配置中的刷新令牌的服务,而无需 UI。如果交互选项有限(例如通过 SSH 进行初始设置),则可以使用设备授权流程,其中应用只需输出 URL。
请注意,必须“发布”OAuth 应用程序才能使刷新令牌真正长期有效,但您无需通过 Google 的限制范围验证 - 您只需比平时多点击几个令人恐惧的屏幕即可。(或者:将您的 Gmail 帐户添加到 Thunderbird,让它进行 OAuth2 设置,然后从其“已保存的密码”对话框中复制刷新令牌。)
(此外,考虑实施标准 OAUTHBEARER 而不是 XOAUTH2。Google 支持这两种机制;它们没有太大区别,但 OAUTHBEARER 变体是“当前”的变体。)