使用当前用户凭据的javamail NTLM身份验证

时间:2014-05-13 11:35:38

标签: java single-sign-on javamail ntlm

如何将JavaMail API与NTLM身份验证一起使用到Exchange服务器,而无需指定用户名和密码,而是自动使用当前登录用户的凭据? (“单点登录”)

我的目的是让我的客户端程序(在我公司的网络中的Windows机器上运行)能够发送电子邮件而无需指定凭据,并且由于安全考虑而不必为网络中的计算机进行中继。 (最后我想用log4j的SmtpAppender结合系统属性覆盖来做到这一点,但我在下面创建了SSCCE来调试问题。)

如果我指定了用户名和与之对应的有效Windows密码,我能够成功使用NTLM身份验证来发送电子邮件:

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailTest {

    public static void main(String[] args) {
        String from = "myusername@mydomain.nl";
        String to = "anotherusername@mydomain.nl";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", "myserver.mydomain");
        props.put("mail.debug", "true");

        props.put("mail.smtp.auth.mechanisms", "NTLM");
        props.put("mail.smtp.auth.ntlm.domain", "mydomain");

        final String username = "myusername";
        final String password = "mypassword";
        Session session =
                Session.getInstance(props, new javax.mail.Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(to));
            message.setSubject("Testing!");
            message.setText("Hello world!");
            Transport.send(message);

            System.out.println("Sent message successfully");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

当我使用空白密码时,javax.mail.Authentication失败 FailedException:535 5.7.3身份验证失败。

当我用简单的代码替换代码来创建会话时:

Session session = Session.getInstance(props);

然后抛出以下异常,我可以从调试输出中看到没有尝试连接到服务器:

Exception in thread "main" java.lang.RuntimeException: javax.mail.Authentication
FailedException: failed to connect, no password specified?
        at MailTest.main(MailTest.java:51)
Caused by: javax.mail.AuthenticationFailedException: failed to connect, no passw
ord specified?
        at javax.mail.Service.connect(Service.java:329)
        at javax.mail.Service.connect(Service.java:176)
        at javax.mail.Service.connect(Service.java:125)
        at javax.mail.Transport.send0(Transport.java:194)
        at javax.mail.Transport.send(Transport.java:124)

1 个答案:

答案 0 :(得分:1)

我不确定没有用户名和密码就可以做到这一点。可能您可以编写一些特定于Windows的代码,这些代码可以从本地身份验证服务检索用户名和密码,然后将其传递给JavaMail。 JavaMail本身当然无法做到这一点。

此外,您可能希望升级到JavaMail 1.5.2,尽管它不会帮助您解决此问题。