You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Google服务账号SMTP XOAUTH2发件报555语法错误求助

问题

我配置了如下环境,尝试通过Google服务账号获取access token,使用OAUTH2认证并通过SMTPTransport发送邮件:

邮件会话配置

<mailSession description="SMTP javax.mail.session" from="someone.iam.gserviceaccount.com">
    <property name="mail.smtp.host" value="smtp.gmail.com"/>
    <property name="mail.smtp.auth" value="true"/>
    <property name="mail.smtp.port" value="587"/>
    <property name="mail.smtp.ssl.enable" value="false"/>
    <property name="mail.smtp.sasl.enable" value="true"/>
    <property name="mail.smtp.ehlo" value="false"/>
    <property name="mail.smtp.sasl.mechanisms" value="XOAUTH2"/>
    <property name="mail.smtp.auth.plain.disable" value="true"/>
    <property name="mail.smtp.auth.login.disable" value="true"/>
    <property name="mail.smtp.starttls.required" value="true"/>
    <property name="mail.smtp.ssl.protocols" value="TLSv1.2"/>
    <property name="mail.smtp.connectiontimeout" value="10000"/>
</mailSession>

获取Access Token代码

try (FileInputStream serviceAccountStream = new FileInputStream(credentialsPath)) { 
    credentials = ServiceAccountCredentials.fromStream(serviceAccountStream).createScoped(Collections.singleton("https://mail.google.com/"));
    credentials.refresh();
    accessToken = credentials.getAccessToken();
    System.out.println("Access token2: " + accessToken.getTokenValue());
}

认证代码(执行失败)

SMTPTransport transport = new SMTPTransport(session, null);
transport.connect("smtp.gmail.com", 587, "sender@example.com", accessToken);

报错信息

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 ""
DEBUG SMTP: protocolConnect login, host=smtp.gmail.com, user=sample-service@gmail.iam.gserviceaccount.com, password=<non-null>
DEBUG SMTP: Authenticate with SASL
DEBUG SMTP: SASL mechanisms allowed: XOAUTH2
DEBUG SMTP: SASL Mechanisms:
DEBUG SMTP:  XOAUTH2
DEBUG SMTP: 
DEBUG SMTP: SASL client XOAUTH2
DEBUG SMTP: SASL callback length: 2
DEBUG SMTP: SASL callback 0: javax.security.auth.callback.NameCallback@66fdec9
DEBUG SMTP: SASL callback 1: javax.security.auth.callback.PasswordCallback@57abad67
AUTH XOAUTH2 dXNlcj1zYW1wbGUtc2VydmljZUBnbWFpbC5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbWF1dGg9QmVhcmVyIHlhMjkuYy5iMFZoZHNTVUhBanNvSldTT0lXU3VkbHNqc25zaXVoc2xpdW5hdVNVSDEzOHJsczgzbGFqYXFhaGhzOHVzaWRmamhza3VkYWRESAo=
555 5.5.2 Syntax error, goodbye. f17-40040a170904ab9100b001922d98cb4esm19571022plr.288 - gsmtp
DEBUG SMTP: SASL authentication failed
javax.mail.AuthenticationFailedException: failed to connect
    at javax.mail.Service.connect(Service.java:403)

发件人和收件人格式为someone@gmail.example.com,使用Google应用密码可正常认证连接,已尝试修改邮件格式、配置用户委托,但问题仍存在,请问该错误的原因是什么?


原因分析与解决方案

核心原因:XOAUTH2认证字符串格式不合法

调用transport.connect时直接传入accessToken对象,不符合Google XOAUTH2的SMTP认证规范。JavaMail默认生成的认证字符串结构错误,导致服务器返回555 5.5.2 Syntax error。

具体修复步骤

  1. 手动构建标准XOAUTH2认证串
    Google要求的XOAUTH2认证格式为:
user=<发件人邮箱>\x01auth=Bearer <access_token>\x01\x01

需将该字符串Base64编码后作为认证参数发送。

  1. 修改认证代码逻辑
    放弃transport.connect的重载方法,手动处理SASL认证流程:
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// 建立连接(不传递认证信息)
SMTPTransport transport = new SMTPTransport(session, null);
transport.connect("smtp.gmail.com", 587, null, null);

// 构建并编码XOAUTH2认证字符串
String xoauth2Payload = String.format("user=%s\x01auth=Bearer %s\x01\x01", 
    "sender@example.com", accessToken.getTokenValue());
String encodedPayload = Base64.getEncoder().encodeToString(xoauth2Payload.getBytes(StandardCharsets.UTF_8));

// 发送认证命令,预期返回235表示成功
transport.issueCommand("AUTH XOAUTH2 " + encodedPayload, 235);
  1. 修正邮件会话配置
    将mail.smtp.ehlo设置为true,EHLO是SMTP协议的必要握手步骤,关闭它会导致服务器无法正确解析后续认证请求:
<property name="mail.smtp.ehlo" value="true"/>
  1. 验证用户委托配置
    确认服务账号已正确配置域范围委派:
  • 在Google Admin控制台开启服务账号的域范围委派权限
  • 授权范围包含https://mail.google.com/
  • 确保发件人邮箱所属的G Suite域已批准该服务账号的委托请求

内容的提问来源于stack exchange,提问作者Emmanuel Shedu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:04:57