通过具有 SSO 身份验证的 Exchange 服务器的 JavaMail

JavaMail through Exchange server with SSO Authentication

我看过一些帖子,它们提供了与我的情况非常相似的解决方案,但无论出于何种原因,它对我来说都不起作用。

例如,here it's presented as a working sample illustrating OP's related problem and here 作为实际答案。

我需要使用 SSO 用户 ID 和密码通过 SMTP 以我自己的身份从我的 Exchange 帐户发送电子邮件。这一切都发生在受限的企业环境中。

根据我从调试信息中了解到的情况,我已成功连接到 SMTP 服务器,然后使用 530 5.7.1 Client was not authenticated 进行用户身份验证失败。 NTLM 身份验证本身似乎已启用。

调试:

DEBUG: setDebug: JavaMail version 1.5.4
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "server.bank.com", port 25, isSSL false
220 server1.corp.bank.com Microsoft ESMTP MAIL Service ready at Mon, 24 Aug 2015 17:15:24 -0400
DEBUG SMTP: connected to host "server.bank.com", port: 25

EHLO server2.corp.bank.com
250-server1.corp.bank.com Hello [xxx.xxx.xxx.xxx]
250-SIZE
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-X-ANONYMOUSTLS
250-AUTH NTLM LOGIN
250-X-EXPS GSSAPI NTLM
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250-XEXCH50
250-XRDST
250 XSHADOW
DEBUG SMTP: Found extension "SIZE", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "X-ANONYMOUSTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM LOGIN"
DEBUG SMTP: Found extension "X-EXPS", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "XEXCH50", arg ""
DEBUG SMTP: Found extension "XRDST", arg ""
DEBUG SMTP: Found extension "XSHADOW", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<first.last@bank.com>
530 5.7.1 Client was not authenticated
DEBUG SMTP: got response code 530, with response: 530 5.7.1 Client was not authenticated

我的代码的重要部分:

static void sendEmail(){

    Properties props = System.getProperties();
    props.setProperty("mail.smtp.host", host);
    props.setProperty("mail.smtp.port", "25");
    // props.setProperty("mail.debug", "true");
    // props.setProperty("mail.debug.auth", "true");
    props.setProperty("mail.smtp.starttls.enable","true");
    props.setProperty("mail.smtp.auth.mechanisms", "NTLM");
    props.setProperty("mail.smtp.auth.ntlm.domain", user_sso_domain);

    // Session session = Session.getDefaultInstance(props);
    Session session = Session.getDefaultInstance(props,
            new javax.mail.Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user_sso_id, user_sso_password);
                }
            });
    session.setDebug(true);

    try {
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(email_from));
        message.addRecipient(Message.RecipientType.TO,
                new InternetAddress(email_to));
        message.setSubject("Test Message");
        message.setText("This is my test message");
        Transport.send(message);

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

非常感谢您提出进一步问题排查的建议。

编辑

实施 中的修复和更好的实践后的工作代码:

private static void sendEmail(){

    Properties props = System.getProperties();
    props.setProperty("mail.smtp.host", host);
    props.setProperty("mail.smtp.port", "25");
    // props.setProperty("mail.debug", "true");
    // props.setProperty("mail.debug.auth", "true");
    props.setProperty("mail.smtp.auth", "true");
    props.setProperty("mail.smtp.starttls.enable","true");
    props.setProperty("mail.smtp.auth.mechanisms", "NTLM");
    props.setProperty("mail.smtp.auth.ntlm.domain", user_sso_domain);

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

    try {
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(email_from));
        message.addRecipient(Message.RecipientType.TO,
                new InternetAddress(email_to));
        message.setSubject("Test Message");
        message.setText("This is my test message");
        Transport.send(message, user_sso_id, user_sso_password);

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

您需要将 "mail.smtp.auth" 设置为 "true"。

或者,更好的是,修复这些 common mistakes 并使您的程序更简单。