Attach client certificates with Axis2?
Asked Answered
J

1

8

Is it possible to easily attach a client certificate to a Axis2 stub generated using wsdl2java? I need to change the client certificate dynamically on a per-request basis, so simply storing it in the keystore won't work for our case.

I've found examples where this is being done for non-SOAP calls, but could not find anything related to using the Axis client stubs. Trying to hack the XML for the SOAP call is an option I guess, albiet a painful one! Groan!

Jacie answered 26/12, 2011 at 22:20 Comment(1)
¿This takes into account that you need the current certificate to retrieve a message with the new certificate? Also, the WS client must be able to replace the certificate in the keystore because it can't live outside the keystore and stay accesible to java.Harlanharland
M
6

If you want to change which certificate is used depending on which connection is made, you'll need to configure an SSLContext to do so, as described in this answer: https://mcmap.net/q/393970/-choosing-ssl-client-certificate-in-java

As far as I know, Axis 2 uses Apache HttpClient 3.x, so you'll need to follow its way of configuring the SSLContext (and X509KeyManager if needed). The easiest way might be to configure Apache HttpClient's global https protocol handler with your SSLContext, set up with an X509KeyManager configured to choose the client certificate as you require (via chooseClientAlias).

If the issuers and the connected Socket (probably the remote address) are not enough for deciding which certificate to choose, you may need to implement a more complex logic which will almost inevitably require careful synchronization with the rest of your application.

EDIT:

Once you've built your SSLContext and X509KeyManager, you need to pass them to Apache HttpClient 3.x. For this, you can build your own SecureProtocolSocketFactory, which will build the socket from this SSLContext (via an SSLSocketFactory, see SSLContext methods). There are examples in the Apache HttpClient 3.x SSL guide. Avoid EasySSLProtocolSocketFactory, since it won't check any server cert (thereby allowing for MITM attacks). You could also try this implementation.

Note that you only really need to customize your X509KeyManager, you can initialize your SSLContext (via init) with null for the other parameters to keep the default values (in particular the default trust settings).

Then, "install" this SecureProtocolSocketFactory globally for Apache HttpClient 3.x using something like this:

Protocol.registerProtocol("https", new Protocol("https",
   (ProtocolSocketFactory)secureProtocolSocketFactory, 443));
Marcasite answered 26/12, 2011 at 22:50 Comment(4)
Thanks, useful info. So I need to do this: httpclient.getHostConfiguration().setHost("www.whatever.com", 443, myhttps); How does one get hold of the httpClient within Axis2 - I've got a org.apache.axis2.client.Stub and ServiceClient, but how do I get hold of the underlying httpClient from these instances?Jacie
I've tried an approach similar to the other post https://mcmap.net/q/393970/-choosing-ssl-client-certificate-in-java But I keep getting this exception regardless of whether I use EasySSLProtocolSocketFactory or StrictSSLProtocolSocketFactory: org.apache.commons.ssl.ProbablyBadPasswordException: Probably bad JKS-Key password: java.security.UnrecoverableKeyException: Password must not be nullJacie
@Sunny, it sounds like a password problem on your keystore. Independently of your X509KeyManager, you'll need to be able to load the private key and cert from your keystore once the alias. You could look into "wrapping" the default X509KeyManager and only override your logic for choosing the alias (you could use this as a starting point, except for client aliases).Marcasite
Thanks for the help @Bruno, much appreciated. However, I just can't shake that exception even with a simple one line call to the constructor. Details here: #8663858Jacie

© 2022 - 2024 — McMap. All rights reserved.