Exchange 服务器将不接受 javax.mail API 提供的用户名/密码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1219404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exchange server will not accept username/password provided with javax.mail API
提问by vy32
I have a lovely little Java client that sends signed email messages. We have an Exchange server that requires username/password authentication to send a message.
我有一个可爱的小型 Java 客户端,可以发送签名的电子邮件。我们有一个需要用户名/密码身份验证才能发送消息的 Exchange 服务器。
When I connect to the exchange server, I get this error:
当我连接到交换服务器时,出现此错误:
avax.mail.AuthenticationFailedException: failed to connect
at javax.mail.Service.connect(Service.java:322)
at javax.mail.Service.connect(Service.java:172)
When I connect to other servers (Unix servers), I have no problem.
当我连接到其他服务器(Unix 服务器)时,我没有问题。
Below is the full debug trace. I can't figure it out.
以下是完整的调试跟踪。我想不通。
DEBUG: JavaMail version 1.4.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SM}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], }
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "SERVER", port 25, isSSL false
220 SERVER ESMTP (deca81216f2ecf4fd6fedb030e3dcfd0)
DEBUG SMTP: connected to host "SERVER", port: 25
EHLO CLIENT
250-SERVER Hello CLIENT [192.1.1.1], pleased to meet you
250-STARTTLS
250-PIPELINING
250-SIZE 100000000
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-8BITMIME
250 HELP
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "100000000"
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
STARTTLS
220 Ready to start TLS
EHLO CLIENT
250-SERVER Hello CLIENT [192.1.1.1], pleased to meet you
250-PIPELINING
250-SIZE 100000000
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-8BITMIME
250 HELP
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "100000000"
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5
AUTH LOGIN
334 VXNlcn5hbWU6
RVJOXHNsK2FyZmlu
334 UGFzc3dvcmQ6
UVdFUnF3ZXIxMjM0IUAjJA==
535 Error: authentication failed
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "SERVER", port 25, isSSL false
220 SERVER ESMTP (deca81216f2ecf4fd6fedb030e3dcfd0)
DEBUG SMTP: connected to host "SERVER", port: 25
EHLO CLIENT
250-SERVER Hello CLIENT [192.1.1.1], pleased to meet you
250-STARTTLS
250-PIPELINING
250-SIZE 100000000
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-8BITMIME
250 HELP
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "100000000"
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
STARTTLS
220 Ready to start TLS
EHLO CLIENT
250-SERVER Hello CLIENT [192.1.1.1], pleased to meet you
250-PIPELINING
250-SIZE 100000000
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-8BITMIME
250 HELP
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "100000000"
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "HELP", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5
AUTH LOGIN
334 VXNlcm5hbWU6
RVJOXHNsZ2FyZmlu
334 UGFzc3dvcmQ6
UVdFUnF3ZXIxMjM0IUAjJA==
535 Error: authentication failed
Error sending mail: failed to connect
javax.mail.AuthenticationFailedException: failed to connect
at javax.mail.Service.connect(Service.java:322)
at javax.mail.Service.connect(Service.java:172)
at SignMessage.sendSigned(SignMessage.java:248)
at SignMessage.main(SignMessage.java:340
采纳答案by javashlook
Apparently, MS Exchange SSL connection is not established properly by Java Mail API. It relies on using SSLSocketFactory
for that, but, if I remember correctly, MS Exchange requires a somewhat mixed approach.
显然,Java Mail API 没有正确建立 MS Exchange SSL 连接。它依赖于使用SSLSocketFactory
,但是,如果我没记错的话,MS Exchange 需要一种有点混合的方法。
Anyway, I have this piece of code in one of my projects:
无论如何,我在我的一个项目中有这段代码:
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class ExchangeSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory sslSocketFactory;
private SocketFactory socketFactory;
public ExchangeSSLSocketFactory() {
try {
socketFactory = SocketFactory.getDefault();
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EmptyTrustManager() }, null);
sslSocketFactory = (SSLSocketFactory)context.getSocketFactory();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private final class EmptyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] cert, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] cert, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}
public static SocketFactory getDefault() {
return new ExchangeSSLSocketFactory();
}
@Override
public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
return sslSocketFactory.createSocket(socket, s, i, flag);
}
@Override
public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
return socketFactory.createSocket(inaddr, i, inaddr1, j);
}
@Override
public Socket createSocket(InetAddress inaddr, int i) throws IOException {
return socketFactory.createSocket(inaddr, i);
}
@Override
public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
return socketFactory.createSocket(s, i, inaddr, j);
}
@Override
public Socket createSocket(String s, int i) throws IOException {
return socketFactory.createSocket(s, i);
}
@Override
public Socket createSocket() throws IOException {
return socketFactory.createSocket();
}
@Override
public String[] getDefaultCipherSuites() {
return sslSocketFactory.getSupportedCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return sslSocketFactory.getSupportedCipherSuites();
}
}
You tell the Java Mail API to use this socket factory by setting following properties:
您可以通过设置以下属性告诉 Java Mail API 使用此套接字工厂:
ssl.SocketFactory.provider
mail.smtp.socketFactory.class
ssl.SocketFactory.provider
mail.smtp.socketFactory.class
to full class name of ExchangeSSLSocketFactory
到全班级名称 ExchangeSSLSocketFactory
From your debug output, it seems that you already have:
从您的调试输出来看,您似乎已经拥有:
mail.smtp.starttls.enable
set to true
mail.smtp.starttls.enable
设置为真
With all this in place, the problem should be solved.
有了这一切,问题就应该得到解决。
回答by javashlook
I had the same issues. Now it works properly. I disabled the antivirus (McAfee) and corrected the user name (I unnecessarily gave the domain whereas it was not required).
我有同样的问题。现在它可以正常工作。我禁用了防病毒软件 (McAfee) 并更正了用户名(我不必要地提供了域,而它不是必需的)。
回答by Sam Barnum
Try disabling plain login explicitly:
尝试明确禁用普通登录:
properties.setProperty("mail." + protocol + ".auth.plain.disable", "true");
OR
或者
props.put("mail.smtp.auth.plain.disable", true);
Apparently there's a bug in some versions of exchange where it advertises support for plain auth when in fact that will always fail.
显然,在某些版本的交换中存在一个错误,它宣传对普通身份验证的支持,而实际上这总是会失败。