我想将自定义信任管理器分配给特定的org.apache.axis.client.Call。使用Java中的常规HTTP客户端,我只需创建一个SSLContext和TrustManager。
这可能在Apache Axis中以某种方式出现吗?
答案 0 :(得分:3)
这在Apache Axis中非常有用,当您考虑创建自定义SSLContext和TrustManager时,您就会发现这一点。您可以创建一个实现Axis SecureSocketFactory接口的类,并定义一个将返回自定义Socket的create()方法。在调用您的调用之前,您必须通过以下代码行告诉Axis您要使用此自定义套接字工厂:
AxisProperties.setProperty("axis.socketSecureFactory", "com.ade.martini.YourSecureSocketFactory");
之后,您可以照常调用Axis调用:
Service service = new Service();
Call call = (Call) service.createCall();
// set your endpoint, operation, etc.
call.invoke(...);
以下是YourSecureSocketFactory
类的外观:
package com.ade.martini;
import org.apache.axis.components.net.BooleanHolder;
import org.apache.axis.components.net.SecureSocketFactory;
import javax.net.ssl.*;
import java.io.*;
import java.net.Socket;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Hashtable;
public class YourSecureSocketFactory implements SecureSocketFactory {
private String KEYSTORE_TYPE = "JKS";
private String PROTOCOL = "SSL";
private String ALGORITHM = "SunX509";
private int DEFAULT_PORT = 443;
protected SSLSocketFactory sslFactory = null;
private String keystoreFile;
private String keystorePass;
private KeyStore kstore = null;
public AxisSecureSocketFactory(Hashtable attributes) {
}
public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL)
throws Exception {
if (sslFactory == null) initFactory();
if (port<=0) port = DEFAULT_PORT;
Socket sslSocket = sslFactory.createSocket(host, port);
return sslSocket;
}
protected void initFactory() throws IOException {
/* One way to find certificates */
keystoreFile = "yourkeystore.jks";
keystorePass = "password";
try {
SSLContext sslContext = getContext();
sslFactory = sslContext.getSocketFactory();
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e.getMessage());
}
}
/* this method will accept all certificates and therefore should NOT
be used in most production settings */
private TrustManager[ ] getTrustManagers() {
TrustManager[ ] certs = new TrustManager[ ] {
new X509TrustManager() {
public X509Certificate[ ] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[ ] certs, String t) { }
public void checkServerTrusted(X509Certificate[ ] certs, String t) { }
}
};
return certs;
}
protected SSLContext getContext() throws Exception {
kstore = initKeyStore(keystoreFile, keystorePass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(ALGORITHM);
kmf.init(kstore, keystorePass.toCharArray());
SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
sslContext.init(kmf.getKeyManagers(), getTrustManagers(), new SecureRandom());
return (sslContext);
}
private KeyStore initKeyStore(String keystoreFile, String keystorePass)
throws IOException {
try {
KeyStore kstore = KeyStore.getInstance(KEYSTORE_TYPE);
ClassLoader classLoader = YourSecureSocketFactory.class.getClassLoader();
File file = new File(classLoader.getResource(keystoreFile).getFile());
InputStream istream = new FileInputStream(file);
kstore.load(istream, keystorePass.toCharArray());
return kstore;
} catch (FileNotFoundException fnfe) {
throw fnfe;
} catch (IOException ioe) {
throw ioe;
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException("Exception trying to load keystore " + keystoreFile + ": " + ex.getMessage());
}
}
}
如果在create()
方法中放置断点,您会注意到在调用Axis调用时它会被执行。看到正在执行此代码是确认Axis正在使用您的自定义套接字以及我们定义的自定义TrustManager。
请注意,我在示例代码中使用的TrustManager将接受来自服务器的所有证书。这通常不是您想要的生产行为。