如何解决javax.mail.AuthenticationFailedException问题?

17

我正在使用JavaMail实现一个sendMail Servlet。输出结果中出现了javax.mail.AuthenticationFailedException异常。请问有人能帮助我解决吗?谢谢。

sendMail Servlet代码:

try {
        String host = "smtp.gmail.com";
        String from = "my@gmail.com";
        String pass = "pass";
        Properties props = System.getProperties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", pass);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true");

        Session session = Session.getDefaultInstance(props, null);
        MimeMessage message = new MimeMessage(session);
        Address fromAddress = new InternetAddress(from);
        Address toAddress = new InternetAddress("test1@gmail.com");

        message.setFrom(fromAddress);
        message.setRecipient(Message.RecipientType.TO, toAddress);

        message.setSubject("Testing JavaMail");
        message.setText("Welcome to JavaMail");
        Transport transport = session.getTransport("smtp");
        transport.connect(host, from, pass);
        message.saveChanges();
        Transport.send(message);
        transport.close();

    }catch(Exception ex){

        out.println("<html><head></head><body>");
        out.println("ERROR: " + ex);
        out.println("</body></html>");
    }

GlassFish 2.1 上的输出:

DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP 36sm10907668yxh.13
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587
EHLO platform-4cfaca
250-mx.google.com at your service, [203.126.159.130]
250-SIZE 35651584
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 PIPELINING
DEBUG SMTP: Found extension "SIZE", arg "35651584"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO platform-4cfaca
250-mx.google.com at your service, [203.126.159.130]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250 PIPELINING
DEBUG SMTP: Found extension "SIZE", arg "35651584"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Attempt to authenticate
AUTH LOGIN
334 VXNlcm5hbWU6
aWpveWNlbGVvbmdAZ21haWwuY29t
334 UGFzc3dvcmQ6
MTIzNDU2Nzhf
235 2.7.0 Accepted
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true

异常发生的确切时间是什么时候?我在你的日志中没有看到它。 - Valentin Rocher
6个回答

20
你需要实现一个自定义的 Authenticator
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;


class GMailAuthenticator extends Authenticator {
     String user;
     String pw;
     public GMailAuthenticator (String username, String password)
     {
        super();
        this.user = username;
        this.pw = password;
     }
    public PasswordAuthentication getPasswordAuthentication()
    {
       return new PasswordAuthentication(user, pw);
    }
}

现在在Session中使用它。

Session session = Session.getInstance(props, new GMailAuthenticator(username, password));

还要查看JavaMail FAQ


@n002213f :当我通过jndi调用(mboss)从mailservice.xml获取会话时,我该如何使用这个GMAILAuthenticator? - Ashwin
@Ashwin - 看看类似问题的答案:https://dev59.com/pk_Ta4cB1Zd3GeqPDsA1 - n002213f
@n002213f:你提供了一个很棒的解决方案,现在我正在实施它,只需将SMTP Gmail服务器替换为我的自己的SMTP服务器名称,但是出现了java.lang.NoClassDefFoundError: javax/mail/Authenticator错误(因为我是在jsp / servlet的帮助下实施它)...有任何建议吗? - user1645434
很棒的答案,但我更喜欢第二个(Uma的回答)。我的身份验证器可以使用,但谷歌的标准(幸运地)太严格了。尽管如此,还是点赞。 - Phil C.
我遇到了完全相同的问题,尝试了这个和第二个答案。两者都对我无效,我正在使用Tomcat作为Web容器。 - viveksinghggits

20

2
哦,谢谢 :)。我为此苦苦挣扎了很长时间。这不应该发生在任何人身上。因此,我使其清晰明了。Phil C - UmaShankar
它对我有效,但如何使其在无需允许不安全应用程序使用IMAP的情况下工作? - gouessej

2
我在下面的代码行中缺少这个身份验证器对象参数。
Session session = Session.getInstance(props, new GMailAuthenticator(username, password));

这行代码解决了我的问题,现在我可以通过Java应用程序发送邮件。其余的代码就像上面一样简单。


1

0
问题在于,您正在创建一个transport对象并使用其连接方法进行身份验证。 但是,然后您使用静态方法发送消息,这忽略了对象执行的身份验证。
因此,您应该在对象上使用sendMessage(message, message.getAllRecipients())方法或像其他人建议的那样使用认证器来通过会话进行授权。
这里是Java Mail FAQ,您需要阅读。

0

想和大家分享一下:
我在更换Digital Ocean机器(IP地址)后遇到了这个错误。显然,Gmail将其识别为黑客攻击。按照他们的指示,批准新的IP地址后,代码恢复正常运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接