Creating SSL client with Axis2/Java
I'm trying to connect to the WebService that uses SSL but no success. I use Axis2, I found some usefull article: http://people.apache.org/~dumindu/do开发者_运维问答cs/HowToConfigureSSL.html, but it is for C. In this article they set pathes to SERVER_CERT, KEY_FILE and SSL_PASSPHRASE using axis2.xml or C coding. I tried to change configuration file but this doesn't work for me. If somebody know how to set this parameters from within Java code, let me know.
I initialized EasySSLProtocolSocketFactory and Protocol instances for different endpoints and register the protocol with unique key like this:
/**
* This method does the following:
* 1. Creates a new and unique protocol for each SSL URL that is secured by client certificate
* 2. Bind keyStore related information to this protocol
* 3. Registers it with HTTP Protocol object
* 4. Stores the local reference for this custom protocol for use during furture collect calls
*
* @throws Exception
*/
public void registerProtocolCertificate() throws Exception {
EasySSLProtocolSocketFactory easySSLPSFactory = new EasySSLProtocolSocketFactory();
easySSLPSFactory.setKeyMaterial(createKeyMaterial());
myProtocolPrefix = (HTTPS_PROTOCOL + uniqueCounter.incrementAndGet());
Protocol httpsProtocol = new Protocol(myProtocolPrefix,(ProtocolSocketFactory) easySSLPSFactory, port);
Protocol.registerProtocol(myProtocolPrefix, httpsProtocol);
log.trace("Protocol [ "+myProtocolPrefix+" ] registered for the first time");
}
/**
* Load keystore for CLIENT-CERT protected endpoints
*/
private KeyMaterial createKeyMaterial() throws GeneralSecurityException, Exception {
KeyMaterial km = null;
char[] password = keyStorePassphrase.toCharArray();
File f = new File(keyStoreLocation);
if (f.exists()) {
try {
km = new KeyMaterial(keyStoreLocation, password);
log.trace("Keystore location is: " + keyStoreLocation + "");
} catch (GeneralSecurityException gse) {
if (logErrors){
log.error("Exception occured while loading keystore from the following location: "+keyStoreLocation, gse);
throw gse;
}
}
} else {
log.error("Unable to load Keystore from the following location: " + keyStoreLocation );
throw new CollectorInitException("Unable to load Keystore from the following location: " + keyStoreLocation);
}
return km;
}
When I have to invoke the web service, I do this (which basically replace "https" in the URL with https1, or https2 or something else depending on the Protocol you initialized for that particular endpoint):
httpClient.getHostConfiguration().setHost(host, port,Protocol.getProtocol(myProtocolPrefix));
initializeHttpMethod(this.url.toString().replace(HTTPS_PROTOCOL, myProtocolPrefix));
It works like a charm!
You may be interested in this answer to a similar question. In particular, Axis 2 seems to be using Apache HttpClient 3.x, according to this document:
If you want to perform SSL client authentication (2-way SSL), you may use the Protocol.registerProtocol feature of HttpClient. You can overwrite the "https" protocol, or use a different protocol for your SSL client authentication communications if you don't want to mess with regular https. Find more information at http://jakarta.apache.org/commons/httpclient/sslguide.html
(You can build your SSLContext from your existing keystore, and configure HttpClient 3.1 using this socket factory.)
Ok so it's >10 years later, but anyways. This could have saved me some time today :)
Create a custom HttpClient with SSLContext:
public static HttpClient sslEnabledHttpClient(final URL ks, final char[] storePass,
final URL ts, final char[] tsPass) {
try {
//Minimalistic SSLContext.
final SSLContextBuilder builder = SSLContexts.custom()
.loadKeyMaterial(ks, storePass, storePass);
if (ts != null) {
builder.loadTrustMaterial(ts, tsPass);
}
final SSLContext sslContext = builder.build();
return HttpClientBuilder.create().setSSLContext(sslContext).build();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
And use that:
// Out of the box Axis2 does not support SSL with client authentication.
// So we need a custom HttpClient.
final HttpClient client = Util.sslEnabledHttpClient(
this.keyStoreURL, this.keyStorePassword.toCharArray(),
this.trustStoreURL, this.trustStorePassword.toCharArray());
myStub._getServiceClient().getOptions().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, client);
精彩评论