我要解决的问题是通过 Exchange 2007 SMTP 中继从我的 tomcat Web 应用程序发送电子邮件。
交换服务器没有安装有效的 SSL 证书,所以我试图推送我自己的 ssl 套接字工厂,它也接受无效的证书。
在堆栈溢出的帮助下,我找到了一个可以在简单测试程序中运行的解决方案,但在从正在运行的 Web 应用程序中执行时却不行(类加载问题)。
我目前的解释是 SocketFetcher 类的类加载器无法看到我的 webapp 的类,对吗?
我该如何解决这个限制?
只是为了好玩,我把我的工厂放在一个单独的 jar 中,并将它放在 tomcat lib 文件夹中,但仍然找不到。
我得到这个例外:
Caused by: java.lang.ClassNotFoundException: com.mypackage.MyTrustAllSslSocketFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:104)
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:247)
... 25 more
我这样推工厂:
Security.setProperty("ssl.SocketFactory.provider", MyTrustAllSslSocketFactory.class.getName());
我的自定义套接字工厂:
public class MyTrustAllSslSocketFactory extends SSLSocketFactory
{
private SSLSocketFactory m_sslSocketFactory;
public MyTrustAllSslSocketFactory() throws Exception
{
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { new TrustAllX509Manager() }, new SecureRandom());
m_sslSocketFactory = sslContext.getSocketFactory();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException
{
return m_sslSocketFactory.createSocket(s, host, port, autoClose);
}
@Override
public String[] getDefaultCipherSuites()
{
return m_sslSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites()
{
return m_sslSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException
{
return m_sslSocketFactory.createSocket(host, port);
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException
{
return m_sslSocketFactory.createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException
{
return m_sslSocketFactory.createSocket(host, port, localHost, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
{
return m_sslSocketFactory.createSocket(address, port, localAddress, localPort);
}
}
和“信任所有人”经理:
public class TrustAllX509Manager implements X509TrustManager
{
@Override
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType)
{
// nothing
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
{
// nothing
}
}