Java Mailサーブレットを実装しようとしています。最初のステップはIMAPサーバーへの接続です。
ポート143(デフォルトのIMAPポート)でサーバーにTelnet接続できます、Telnetは次のように言っています:_OK The Microsoft Exchange IMAP4 service is ready.
_
Java Mail APIを使用して、次のようにサーバーに接続しようとしています。
_Properties props = new Properties();
session = Session.getDefaultInstance(props, null);
store = session.getStore("imap");
store.connect("Host","user","password");
_
また、Javaで渡そうとしているのと同じ資格情報を持つ既存のOutlook Webappを使用して、この同じサーバーに接続できます。
しかし、これをsession.setDebug(true)
で実行すると、次の出力が生成されます。
_DEBUG: setDebug: JavaMail version 1.4.5
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 "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, Host=myHost, user=myUser, password=<non-null>
javax.mail.MessagingException: No login methods supported!;
_
編集:
提案どおりprop.setProperty("mail.imap.starttls.enable", "true")
を追加しました。
しかし、私はこのデバッグ出力を取得し始めました:
_DEBUG: setDebug: JavaMail version 1.4.5
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: enable STARTTLS
DEBUG: trying to connect to Host "myHost", port 143, isSSL false
* OK The Microsoft Exchange IMAP4 service is ready.
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG: protocolConnect login, Host=myHost, user=myUser, password=<non-null>
A1 STARTTLS
A1 OK Begin TLS negotiation now.
DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
_
これが証明書の問題であると想定して、私は これらの指示 に従い、メールサーバーをcacertsファイルに追加しました。そこに含まれているテストプログラムは完全に正常に実行され、SSL URLを使用して接続できましたが、Javaメールクラスを実行すると、同じ例外が発生しました。
session.getStore("imaps")
で "imaps"に変更しようとしましたが( "imap"ではなく)、 "Microsoft Exchange Serverの準備ができました"というメッセージを受け取ることさえできませんでした。 「imaps」が指定されたときは常にポート993で接続しようとしているためだと思います。ただし、ポート993にTelnetを使用しても、電子メールサーバーへの接続は表示されません。
そこで、次のようにポート143でSSLを使用するようにプログラムに強制しようとしました。
_// Use SSL
prop.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.fallback", "false");
// Use port 143
prop.setProperty("mail.imap.port", "143");
prop.setProperty("mail.imap.socketFactory.port", "143");
_
この例外を受け取るだけなので、SSLとは何の関係もありません。
_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 "myHost", port 143, isSSL false
Not able to process the mail reading.
javax.mail.MessagingException: Unrecognized SSL message, plaintext connection?;
_
上記のTLS例外(_DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException:
_)は、TLSがExchange Serverで有効になっていないために発生しますか?
私は電子メールサーバーにアクセスする準備ができていませんが、おそらく誰かに入れてもらうことができます。
解決策:
彼の回答の下のHulkingUnicornのコメントが指摘しました この回答 これは必要な正確な処理でした。どうやらMS Exchange Serverにはこの問題があります。その回答にリストされているクラスをパッケージに追加するとともに、メール接続を次のように実装しただけで、すべてが順調でした。
_Properties prop = new Properties();
prop.setProperty("mail.imap.starttls.enable", "true");
prop.setProperty("ssl.SocketFactory.provider", "my.package.name.ExchangeSSLSocketFactory");
prop.setProperty("mail.imap.socketFactory.class", "my.package.name.ExchangeSSLSocketFactory");
session = Session.getDefaultInstance(prop, null);
session.setDebug(true);
store = session.getStore("imap");
store.connect("myHost","myUser","myPassword");
_
com.Sun.mail.util.MailSSLSocketFactory
これは、javamail 1.4.5 APIの一部です。
例:
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.imap.starttls.enable", "true");
props.put("mail.imap.ssl.socketFactory", sf);
カスタムSSLSocketFactoryを使用する必要はありません。