首页 > 解决方案 > 使用服务帐户对 gmail 进行 OAuth2 身份验证

问题描述

我需要在我的 gmail 应用中实现 OAuth2 身份验证。应用程序在没有 UI 的后台运行。所以我有谷歌帐户(我认为那不是 GSuite)。我按照此处的说明创建了一个服务帐户:https ://www.emailarchitect.net/easeendmail/sdk/html/object_oauth_service_account.htm (但没有分配产品 - 我没有选择。可能是因为我的帐户不是 GSuite?...)。之后,我使用 JSON 文件创建了一个用于 JWT 身份验证的密钥。我正在使用google-auth-library-oauth2-http库来生成access_token并使用它来登录 gmail 邮箱。下面是生成令牌的代码片段:

GoogleCredentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream("path_to_json")
                                     .createScoped(Arrays.asList("https://mail.google.com"));
credentials.refreshIfExpired();
AccessToken accessToken = credentials.getAccessToken();

AccessToken 已成功检索,但是当我尝试将其用于邮箱身份验证时,我得到javax.mail.AuthenticationFailedException: [AUTHENTICATIONFAILED] Invalid credentials (Failure).

这是邮箱连接的代码片段:

Properties props = new Properties();
props.put("mail.imap.ssl.enable", "true");
props.put("mail.imap.auth.mechanisms", "XOAUTH2");
Session session = Session.getInstance(props);
Store store = session.getStore("imap");
store.connect("imap.gmail.com", "my_acc@gmail.com", access_token);

问题是是否可以通过基于服务帐户数据生成的 JWT 使用访问令牌对 gmail 邮箱进行身份验证?甚至可能吗?

标签: javajwtgmailjakarta-mailgmail-api

解决方案


您可以在不使用 G Suite 的情况下创建服务帐户,但如果您想访问用户的 Gmail 收件箱,则需要使用“域范围委派”。正如您在文档中所读到的:

在企业应用程序中,您可能希望在没有任何手动授权的情况下以编程方式访问用户的数据。在 G Suite 域中,域管理员可以授予第三方应用程序对其用户数据的域范围访问权限——这称为域范围授权。要以这种方式委派权限,域管理员可以使用具有 OAuth 2.0 的服务帐户。


推荐阅读