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

Postfix与javax.mail连接失败求助:认证异常排查

问题原因分析
  1. 端口不匹配:你启用的是Postfix的submission服务(对应587端口),但Java代码连接的是25端口。25端口默认是Postfix用来接收外部邮件或本地中继的,一般不会强制要求认证;但你代码里开启了mail.smtp.auth=true,这就导致矛盾——Postfix的25端口不需要认证,可代码硬要走认证流程,又没提供密码,直接触发认证失败异常。
  2. 代码缺失认证信息:即使Postfix开启了认证要求,你的代码也没有配置SMTP认证的用户名和密码,这也是抛出AuthenticationFailedException的直接原因。
  3. MIME类型错误:代码里setContent的类型写为plain/text,正确格式应该是text/plain,这个错误虽不影响连接,但会导致后续邮件显示异常。
解决方法

方案一:改用587端口(推荐,符合邮件发送规范)

1. 修改Java代码

调整端口为587,补充认证逻辑,修正MIME类型:

public static void main(String[] args) throws MessagingException {
        Properties prop = new Properties();
        prop.put("mail.smtp.auth", true);
        prop.put("mail.smtp.host", "localhost");
        prop.put("mail.smtp.port", "587"); // 切换到submission服务的587端口
        // 开启TLS加密(Postfix的submission服务默认推荐启用)
        prop.put("mail.smtp.starttls.enable", "true");
        prop.put("mail.smtp.starttls.required", "true");

        // 配置认证信息
        Session session = Session.getInstance(prop, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                // 替换为你在Postfix中配置的SMTP用户名和密码
                return new PasswordAuthentication("your-smtp-username", "your-smtp-password");
            }
        });

        MimeMessage registerMail = new MimeMessage(session);
        try {
                registerMail.setSender(new InternetAddress("xxx@xxx"));
        } catch (MessagingException e) {
                e.printStackTrace();
        }
        registerMail.setRecipients(RecipientType.TO, "xxx@xxx");
        registerMail.setSubject("HI");
        registerMail.setContent("adsf", "text/plain"); // 修正MIME类型
        Transport.send(registerMail);
}

2. 完善Postfix的submission服务配置

打开/etc/postfix/master.cf,确保submission行的完整配置如下(如果只有第一行,补充下面的参数):

127.0.0.1:submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject

执行postfix reload重载服务生效。

3. 配置Postfix的SMTP认证

打开/etc/postfix/main.cf,添加或确保以下配置(以Dovecot作为SASL认证后端为例,这是最常用的配置方式):

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname

之后需要安装并配置Dovecot,确保系统用户或虚拟用户可以通过SASL认证。

方案二:本地测试用(无认证发送,不推荐生产环境)

如果只是本地测试,不需要认证,可以:

  1. 修改Java代码,关闭认证:
prop.put("mail.smtp.auth", false);
  1. 修改Postfix的main.cf,允许本地IP无认证中继:
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

执行postfix reload生效。

密码配置说明

如果使用方案一的认证方式,密码是你在Postfix/SASL后端(比如Dovecot)配置的用户密码——可以是系统用户密码,也可以是虚拟用户密码。在Java代码中通过Authenticator类的getPasswordAuthentication方法传入即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:03:23