Javamail NTLM 身份验证失败
尝试在 JavaMail 中使用 NTLM 连接到 Exchange 服务器。我可以连接到 SMTP,但不能连接到 IMAP。我还可以使用相同的主机/用户名/密码、帐户类型=“IMAP”、端口 143、ssl=false、身份验证=NTLM、域名=“”通过 OS X Mail.app 应用程序进行身份验证。
连接代码:
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Store;
import java.util.Properties;
public class NTLMTest {
public static void main(String[] args) throws Exception {
final String host = "example.com";
final String user = "bob";
final String password = "password";
final Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
session.setDebug(true);
// SMTP CONNECT
final Transport transport = session.getTransport("smtp");
transport.connect(host, user, password);
System.out.println("SMTP Connect successful");
// IMAP CONNECT
final Store store = session.getStore("imap");
store.connect(host, user, password);
System.out.println("IMAP Connect Successful");
}
}
输出:
DEBUG: setDebug: JavaMail version 1.4.3
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "example.com", port 25, isSSL false
220 server18.example.com ESMTP Sendmail 8.14.3/8.14.3/Debian-5+lenny1; Thu, 2 Dec 2010 18:05:30 +0100; (No UCE/UBE) logging access from: xxx.xxx.xxx.xxx
DEBUG SMTP: connected to host "example.com", port: 25
EHLO 192.168.1.107
250-server18.example.com Hello c-xxxx [xxx.xxx.xxx.xxx], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 20971520
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5 LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "20971520"
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ETRN", arg ""
DEBUG SMTP: Found extension "AUTH", arg "DIGEST-MD5 CRAM-MD5 LOGIN PLAIN"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "DELIVERBY", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
AUTH LOGIN
334 VXNlcm5hbWU6
YWR2aWVzZW5raWVzMDU=
334 UGFzc3dvcmQ6
ZGlja2hvbmluZw==
235 2.0.0 OK Authenticated
SMTP Connect successful
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "example.com", port 143, isSSL false
* OK server18.example.com Cyrus IMAP4 v2.1.18-IPv6-Debian-2.1.18-5.1 server ready
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE AUTH=DIGEST-MD5 AUTH=NTLM AUTH=CRAM-MD5 ANNOTATEMORE
A0 OK Completed
IMAP DEBUG: AUTH: DIGEST-MD5
IMAP DEBUG: AUTH: NTLM
IMAP DEBUG: AUTH: CRAM-MD5
DEBUG: protocolConnect login, host=example.com, user=bob, password=<non-null>
DEBUG NTLM: type 1 message: Type1Message[suppliedDomain=,suppliedWorkstation=192.168.1.107,flags=0x00000201]
DEBUG NTLM: type 1 message length: 45
A1 AUTHENTICATE NTLM
+
TlRMTVNTUAABAAAAASIAAAAAAAAAAAAADQANACAAAAAxOTIuMTY4LjEuMTA3
+ TlRMTVNTUAACAAAAAAAAADAAAAABIgAApdhJrA6NzmwAAAAAAAAAAAAAAAAAAAAA
TlRMTVNTUAADAAAAGAAYAEAAAAAwADAAWAAAAAAAAAAAAAAAHAAcAIgAAAAaABoApAAAAAAAAAAAAAAAAQIAALV6mIutJKdZSH4IZGmvNqNFxJafzInd0yJDR4J3oe3LyBls0Y75UuwBAQAAAAAAANAS9yNDkssBVbH5v087iUIAAAAAAAAAAGEAZAB2AGkAZQBzAGUAbgBrAGkAZQBzADAANQAxADkAMgAuADEANgA4AC4AMQAuADEAMAA3AA==
A1 NO authentication failure
Exception in thread "main" javax.mail.AuthenticationFailedException: authentication failure
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:613)
at javax.mail.Service.connect(Service.java:291)
at javax.mail.Service.connect(Service.java:172)
at com.prosc.emailplugin.NTLMTest.main(NTLMTest.java:25)
Disconnected from the target VM, address: '127.0.0.1:56125', transport: 'socket'
Process finished with exit code 1
我尝试用反斜杠包装用户名,按照 http://www.oracle.com/technetwork/java/faq-135477.html#Exchange-login 我收到以下错误:
Exception in thread "main" javax.mail.AuthenticationFailedException: One time use of a plaintext password will enable requested mechanism for user
SMTP 连接部分中用户名周围的反斜杠导致其失败。我无法判断“一次性使用”错误是否是朝着正确方向迈出的一步。
Trying to connect to Exchange server using NTLM in JavaMail. I can connect to SMTP, but not IMAP. I can also authenticate via the OS X Mail.app application using the identical host/username/password, account type = "IMAP", Port 143, ssl=false, authentication=NTLM, Domain Name="".
The connecting code:
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Store;
import java.util.Properties;
public class NTLMTest {
public static void main(String[] args) throws Exception {
final String host = "example.com";
final String user = "bob";
final String password = "password";
final Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
session.setDebug(true);
// SMTP CONNECT
final Transport transport = session.getTransport("smtp");
transport.connect(host, user, password);
System.out.println("SMTP Connect successful");
// IMAP CONNECT
final Store store = session.getStore("imap");
store.connect(host, user, password);
System.out.println("IMAP Connect Successful");
}
}
The output:
DEBUG: setDebug: JavaMail version 1.4.3
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "example.com", port 25, isSSL false
220 server18.example.com ESMTP Sendmail 8.14.3/8.14.3/Debian-5+lenny1; Thu, 2 Dec 2010 18:05:30 +0100; (No UCE/UBE) logging access from: xxx.xxx.xxx.xxx
DEBUG SMTP: connected to host "example.com", port: 25
EHLO 192.168.1.107
250-server18.example.com Hello c-xxxx [xxx.xxx.xxx.xxx], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 20971520
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5 LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "20971520"
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ETRN", arg ""
DEBUG SMTP: Found extension "AUTH", arg "DIGEST-MD5 CRAM-MD5 LOGIN PLAIN"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "DELIVERBY", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
AUTH LOGIN
334 VXNlcm5hbWU6
YWR2aWVzZW5raWVzMDU=
334 UGFzc3dvcmQ6
ZGlja2hvbmluZw==
235 2.0.0 OK Authenticated
SMTP Connect successful
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc]
DEBUG: mail.imap.fetchsize: 16384
DEBUG: mail.imap.statuscachetimeout: 1000
DEBUG: mail.imap.appendbuffersize: -1
DEBUG: mail.imap.minidletime: 10
DEBUG: trying to connect to host "example.com", port 143, isSSL false
* OK server18.example.com Cyrus IMAP4 v2.1.18-IPv6-Debian-2.1.18-5.1 server ready
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE AUTH=DIGEST-MD5 AUTH=NTLM AUTH=CRAM-MD5 ANNOTATEMORE
A0 OK Completed
IMAP DEBUG: AUTH: DIGEST-MD5
IMAP DEBUG: AUTH: NTLM
IMAP DEBUG: AUTH: CRAM-MD5
DEBUG: protocolConnect login, host=example.com, user=bob, password=<non-null>
DEBUG NTLM: type 1 message: Type1Message[suppliedDomain=,suppliedWorkstation=192.168.1.107,flags=0x00000201]
DEBUG NTLM: type 1 message length: 45
A1 AUTHENTICATE NTLM
+
TlRMTVNTUAABAAAAASIAAAAAAAAAAAAADQANACAAAAAxOTIuMTY4LjEuMTA3
+ TlRMTVNTUAACAAAAAAAAADAAAAABIgAApdhJrA6NzmwAAAAAAAAAAAAAAAAAAAAA
TlRMTVNTUAADAAAAGAAYAEAAAAAwADAAWAAAAAAAAAAAAAAAHAAcAIgAAAAaABoApAAAAAAAAAAAAAAAAQIAALV6mIutJKdZSH4IZGmvNqNFxJafzInd0yJDR4J3oe3LyBls0Y75UuwBAQAAAAAAANAS9yNDkssBVbH5v087iUIAAAAAAAAAAGEAZAB2AGkAZQBzAGUAbgBrAGkAZQBzADAANQAxADkAMgAuADEANgA4AC4AMQAuADEAMAA3AA==
A1 NO authentication failure
Exception in thread "main" javax.mail.AuthenticationFailedException: authentication failure
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:613)
at javax.mail.Service.connect(Service.java:291)
at javax.mail.Service.connect(Service.java:172)
at com.prosc.emailplugin.NTLMTest.main(NTLMTest.java:25)
Disconnected from the target VM, address: '127.0.0.1:56125', transport: 'socket'
Process finished with exit code 1
I tried wrapping the username with backslashes, per http://www.oracle.com/technetwork/java/faq-135477.html#Exchange-login I get the following error:
Exception in thread "main" javax.mail.AuthenticationFailedException: One time use of a plaintext password will enable requested mechanism for user
Backslashes around the username in the SMTP connect portion cause it to fail. I can't tell if the "One time use" error is a step in the right direction or not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我注意到 - 通过 SMTP - NTLM 身份验证不适用于旧版本的 javax.mail(最高 1.4.1),但现在适用于版本 1.4.5。
并且要指定的用户名的形式为“域\用户名”。可能同样的效果(javax.mail 版本的差异)也适用于 IMAP。
I have noticed that - via SMTP - the NTLM Authentication did not work with an older version of javax.mail (up to 1.4.1) but it now works with version 1.4.5.
And the user name to be specified was of the form "domain\username". Could be that same effect (difference in versions of javax.mail) would also apply to IMAP.
根据我对 NTLM 的记忆以及您的 NTLM 调试消息,我可以收集到以下信息:
我建议您尝试遵循 JDK 从客户端 Windows 计算机自动获取凭据 (u/p) 的方式。
From what I recall about NTLM, and your NTLM debug messages I can gather the following:
I suggest you try following the road in which the credentials (u/p) are taken automatically by the JDK from the client Windows machine.
这是我完整的工作解决方案:
使用netbeans,创建一个新的java应用程序项目。将此代码放在那里:
将用户名、密码、端口和属性更改为您的特定设置。
您需要获取
javamail-1.4.7
并从 (http://www.oracle.com/technetwork/java/index-138643.html) 到项目中。我们所做的一件事是下载 Thunderbird 邮件客户端,它可以自动发现有关交换服务器的信息,以确保我们的所有设置都正确。如果您无法说服雷鸟进行连接,那么同样不应期望此代码能够工作。
Here is my complete working solution:
Using netbeans, create a new java application project. Put this code in there:
Change the username, passwords, ports, and properties to your specific settings.
You will need to get the
javamail-1.4.7
and load themail.jar
from (http://www.oracle.com/technetwork/java/index-138643.html) into the project.One thing we did which shed light on what our parameters should be is to download Thunderbird mail client which can auto-discover information about the exchange server to make sure all of our settings were right. If you cant convince thunderbird to connect, then this code likewise shouldn't be expected to work.
我在通过 Exchange SMTP 连接器发送电子邮件时遇到了同样的问题。
在发现 javamail 不支持 NTLMv2 身份验证后,我找到了一个需要 JCIFS 库的解决方法。
我下载了javamail api源代码(https://java.net/projects/javamail/pages/ Home)并编辑了 com.sun.mail.auth.Ntlm 类,以使用 JCIFS 库支持添加缺少的 NTLMv2 支持 (http://jcifs.samba.org)。
文件 Ntlm.java 中的第一个修改是在方法 init0 中,包括添加缺少的标志 NTLMSSP_NEGOTIATE_NTLM2:
第二个修改是将方法generateType3Msg 替换为以下内容:
我发现修补库的最简单方法是编译类并更新库 jar 文件:
为了尽可能启用调试,我在测试类的 main 方法中使用了以下代码:
使用此logging.properties:
在应用补丁之前,发送后测试被卡住输入 1 消息,因为我的 Exchange 服务器需要 NTLMv2 身份验证。
打补丁后,认证成功。
另一个解决方案是使用 Microsoft 发布和维护的 ##EWS Java API## 通过 ##Exchange Webservice## 又名 EWS 发送电子邮件 (https://github.com/OfficeDev/ews-java-api),例如本例中:
}
但是内部类中又需要应用一个补丁EwsJCIFSNTLMScheme.java 的 NTLM 启用 NTLMv2,如本文答案中所示:
如何在 Java 中使用 LDAP 身份验证进行 Exchange Web 服务连接?
即:
}
我尝试过,它对我有用。
I had the same problem sending email via Exhange SMTP connector.
After finding out that javamail does not support NTLMv2 authentication, I worked out a workaround that requires JCIFS library though.
I downloded the javamail api source code (https://java.net/projects/javamail/pages/Home) and edited the class com.sun.mail.auth.Ntlm to add the missing support for NTLMv2 using the JCIFS library support (http://jcifs.samba.org).
The first modification in file Ntlm.java was in method init0, and consisted of adding the missing flag NTLMSSP_NEGOTIATE_NTLM2:
The second modification was to replace the method generateType3Msg with this:
The simpest way I found to patch the library is to compile the class and update the library jar file:
To enable debug as much as possible, I used the following code in the main method of my test class:
with this logging.properties:
Before applying the patch the test was stuck after sending Type 1 message, because my Exchange server required NTLMv2 authentication.
After the patch the athentication was done successfully.
Another solution is to send email via the ##Exchange webservice## aka EWS by using the ##EWS Java API## released and mantained by Microsoft (https://github.com/OfficeDev/ews-java-api), such as in this example:
}
But again there is a patch to apply in the inner class NTLM of EwsJCIFSNTLMScheme.java to enable NTLMv2 as indicated in the answer to this post:
How to use LDAP authentication for the Exchange Web Services connection in Java?
That is:
}
I tried and it worked for me.
尝试将域“”设置为 imap 存储的属性:
由于在 SMTP 中您使用 LOGIN 登录,因此不需要使用域。但在 NTLM 中,域是强制性的。
Try setting the domain "" to the properties of the imap store :
Since in SMTP you are login using LOGIN, the use of the domain is not necessary. But in NTLM the domain is mandatory.