Exchange服务器不接受javax.mail API提供的用户名/密码 [英] Exchange server will not accept username/password provided with javax.mail API
问题描述
我有一个可爱的小Java客户端,可以发送已签名的电子邮件。我们有一台需要用户名/密码验证才能发送邮件的Exchange服务器。
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.
当我连接到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)
当我连接到其他服务器时(Unix服务器),我没有问题。
When I connect to other servers (Unix servers), I have no problem.
以下是完整的调试跟踪。我无法弄明白。
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
推荐答案
显然,Java Mail API未正确建立MS Exchange SSL连接。它依赖于使用 SSLSocketFactory
,但是,如果我没记错的话,MS Exchange需要一些混合方法。
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.
无论如何,我在我的一个项目中有这段代码:
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();
}
}
您告诉Java Mail API通过设置以下属性来使用此套接字工厂:
You tell the Java Mail API to use this socket factory by setting following properties:
-
ssl.SocketFactory.provider
-
mail.smtp.socketFactory.class
ssl.SocketFactory.provider
mail.smtp.socketFactory.class
到完整的班级名称 ExchangeSSLSocketFactory
从您的调试输出中,您似乎已经拥有:
From your debug output, it seems that you already have:
-
mail.smtp.starttls.enable
设为true
mail.smtp.starttls.enable
set to true
完成所有这些后,问题应该解决。
With all this in place, the problem should be solved.
这篇关于Exchange服务器不接受javax.mail API提供的用户名/密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!