使用 Oauth2 到 Gmail SMTP 进行身份验证

问题描述 投票:0回答:1

由于 Google 将在其 SMTP 中放弃对 PLAIN 身份验证的支持,我想迁移到基于 OAuth2 的身份验证。

this 文档之后,我开始设置服务帐户并创建 json 格式的密钥。

然后尝试使用此代码进行身份验证:


import com.google.auth.oauth2.ServiceAccountCredentials;
import com.sun.mail.smtp.SMTPTransport;
import jakarta.mail.Session;

import java.io.InputStream;
import java.util.Base64;
import java.util.Collections;
import java.util.Properties;

public class ForSendingEmailOauthAdapater {

  void send() throws Exception {
    InputStream secret = this.getClass().getClassLoader().getResourceAsStream("keys.json");
    String email = "[email protected]"; // in my production code this set to the related service account email
    GoogleCredentials credentials = ServiceAccountCredentials.fromStream(secret)
        .createScoped(Collections.singletonList("https://mail.google.com/"));
    credentials.refreshIfExpired();
    String token = credentials
        .getAccessToken()
        .getTokenValue();

    Properties props = new Properties();
    props.put("mail.smtp", "true");
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
    props.put("mail.smtp.starttls.enable", "true");

    Session session = Session.getInstance(props);
    session.setDebug(true);

    SMTPTransport transport = (SMTPTransport) session.getTransport("smtp");
    transport.connect("smtp.gmail.com", 587, email, null);

    String authString = "user=" + email + "\001auth=Bearer " + token + "\001\001";
    String base64oauth2String = Base64.getEncoder().encodeToString(authString.getBytes());
    transport.issueCommand("AUTH XOAUTH2 " + base64oauth2String, 235);
  }
}

不幸的是失败了:

STARTTLS
220 2.0.0 Ready to start TLS
EHLO <myhostname>
250-smtp.gmail.com at your service, [89.64.21.109]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
AUTH XOAUTH2 <base64 encoded user&token>
555-5.5.2 Syntax error, goodbye. For more information, go to
555-5.5.2  https://support.google.com/a/answer/3221692 and review RFC 5321
555 5.5.2 specifications. a640c23a62f3a-a725f5e1b52sm262436666b.135 - gsmtp

它看起来与此处几乎相同(请参阅 SMTP 部分)。

555-5.5.2 错误表明它是一个无效的电子邮件地址(例如收件人的),但它在身份验证时失败,而不是发送电子邮件的事件失败。

我也通过curl尝试了相同的操作,但失败并出现相同的错误:

  curl -sv --url 'smtp://smtp.gmail.com:587' \
  --ssl-reqd \
  --login-options 'AUTH=XOAUTH2' --oauth2-bearer <access_token> \
  --user <service account email> \
  --mail-from [email protected] --mail-rcpt [email protected]

有什么想法我做错了什么吗?

java oauth-2.0 smtp gmail
1个回答
0
投票

您还有问题吗?

对我来说奇怪的是您试图直接使用服务帐户进行身份验证。这可能是问题的原因,因为它不是 Gmail 帐户 (smtp.gmail.com 是 gmail smtp 服务器)

您链接的指南解释了如何使用服务帐户来模拟用户(仅限工作区)。

您应该尝试使用同意屏幕来作为 Gmail 用户进行身份验证并获取令牌,然后在 xoauth2 身份验证中发送该令牌。

查看Gmail API java 快速入门,您可以使用其中的身份验证流程以 gmail 用户身份登录,然后使用其余代码。我知道您不想使用 Gmail API,我只是链接此示例,因为身份验证过程与您的用例相关。

© www.soinside.com 2019 - 2024. All rights reserved.