2009-08-02 10 views
1

У меня есть прекрасный маленький Java-клиент, который отправляет подписанные сообщения электронной почты. У нас есть сервер Exchange, для которого требуется аутентификация имени пользователя/пароля для отправки сообщения.Сервер Exchange не принимает имя пользователя/пароль, предоставленное с помощью javax.mail API

При подключении к серверу обмена, я получаю эту ошибку:

avax.mail.AuthenticationFailedException: failed to connect 
     at javax.mail.Service.connect(Service.java:322) 
     at javax.mail.Service.connect(Service.java:172) 

При подключении к другим серверам (Unix-сервера), у меня нет никаких проблем.

Ниже приведена полная трассировка отладки. Я не могу понять.

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 
+0

Я помню некоторую подобную вещь с клиентами, не связанными с Java, имя пользователя должно быть в форме DOMAIN \ username и в зависимости от того, как настроен сервер excahnge, вам может понадобиться также суффикс, например, например. companyname \ bob или companyname.COM \ bob или companyname.local \ bob – nos

+0

Да, я тоже попробовал бы это. Добавьте информацию о домене до имени пользователя, это должно помочь. –

ответ

7

По-видимому, соединение MS Exchange SSL не установлено должным образом с помощью Java Mail API. Для этого используется SSLSocketFactory, но, если я правильно помню, MS Exchange требует несколько смешанного подхода.

Во всяком случае, у меня есть этот кусок кода в одном из моих проектов:

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(); 
} 

} 

Вы говорите API Java почты, чтобы использовать этот сокет завод, установив следующие свойства:

  • ssl.SocketFactory.provider
  • mail.smtp.socketFactory.class

до полного названия класса o е ExchangeSSLSocketFactory

Ваш отладочный вывод, кажется, что у вас уже есть:

  • mail.smtp.starttls.enable набор для истинного

С все это в месте, эта проблема должна быть решена.

+0

Спасибо. К сожалению, этого не произошло. У меня есть два сервера Exchange, они оба настроены по-разному, и оба ведут себя одинаково с вашим кодом, как с моим кодом. В обоих случаях серверы говорят, что могут использовать GSSAPI NTLM и LOGIN, а моя система говорит LOGIN PLAIN DIGEST-MD5, поэтому система javax.mail пытается выполнить AUTH LOGIN, и это не работает. Странно. Он работает на любой другой системе, просто не обмениваясь. Есть ли реализация GSSAPI, которую я могу использовать? – vy32

+0

Не связан с проблемой OP, но этот ответ полностью разрешил проблему с поддержкой Exchange Server No No Logon Method Support, с которой я боролся в течение примерно одного дня. Благодаря! – Geronimo

+0

Я знаю, что это супер-старый, но я добавляю импорт пакетов, необходимых для завершения этого ответа. –

0

У меня были те же проблемы. Теперь он работает правильно. Я отключил антивирус (McAfee) и исправил имя пользователя (я без необходимости предоставлял домен, тогда как он не требовался).

+0

Интересно, но я думаю, что вы испытываете эффект наблюдателя. То есть, я не думаю, что сделанные вами изменения привели к тому, что вы наблюдали. – vy32

+0

Я думаю, что это было из-за отключения McAfee. На моем рабочем месте McAfee имеет встроенный брандмауэр (я понятия не имею, входит ли это в комплект McAfee), и брандмауэр блокировал некоторые из приложений. – 2010-01-04 13:04:53

0

Попробуйте отключить простой вход в явном виде:

properties.setProperty("mail." + protocol + ".auth.plain.disable", "true"); 

ИЛИ

props.put("mail.smtp.auth.plain.disable", true); 

Видимо есть ошибка в некоторых версиях обмена, где она рекламирует поддержку простого AUTH, когда на самом деле, что всегда будет терпеть неудачу.