问题
How can I use the JavaMail API with NTLM authentication to an Exchange server without having to specify user name and password but instead automatically use the credentials of the currently logged-in user? ("single sign on")
My intention is to let my client program (which runs on Windows machines in my company's network) to be able to send email without having to specify credentials and without having to allow relay for computers in the network due to security concerns. (In the end I would like to do this with log4j's SmtpAppender in combination with system property overrides, but I creating the SSCCE below to debug the issue.)
I AM able to successfully use NTLM authentication to send email if I specify the user name and the valid Windows password corresponding to it:
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);
}
}
}
When I use a blank password this fails with javax.mail.Authentication FailedException: 535 5.7.3 Authentication unsuccessful.
When I replace the code to create a Session with simply:
Session session = Session.getInstance(props);
then the following exception is thrown and I can see from the debug output that no attempt is made to connect to the server:
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:
I'm not sure there's any way to do this without having the username and password. Possibly you can write some Windows-specific code that can retrieve the username and password from the local authentication service and then pass that in to JavaMail. JavaMail itself certainly has no way to do this.
Also, you might want to upgrade to JavaMail 1.5.2, although it won't help you with this problem.
来源:https://stackoverflow.com/questions/23630160/javamail-ntlm-authentication-using-credentials-of-current-user