Client certificates with HTTPClient 4
I just wrote a small post on how to setup Jetty to support client-side certificates (http://www.smartjava.org/content/embedded-jetty-client-certificates). To easily test the configuration I use the latest HTTPClient from from http://hc.apache.org/httpcomponents-client-ga/. This is a great client, but, once again, the documentation on how to configure this client for two-way ssl isn’t that easy to be found. The following piece of java code uses HTTPClient to make a GET call using client-side certificates. In this example I haven’t defined a specific truststore for this client, since the server certificate is already trusted by my cacerts file.
// read in the keystore from the filesystem, this should contain a single keypair
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream(KEYSTORE_LOCATION),
KEYSTORE_PASS.toCharArray());
// set up the socketfactory, to use our keystore for client authentication.
SSLSocketFactory socketFactory = new SSLSocketFactory(
SSLSocketFactory.TLS,
clientKeyStore,
KEYSTORE_PASS,
null,
null,
null,
(X509HostnameVerifier) SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
// create and configure scheme registry
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, socketFactory));
// create a client connection manager to use in creating httpclients
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry);
// create the client based on the manager, and use it to make the call
httpClient = new DefaultHttpClient(mgr);
// create the method to execute
HttpGet m = new HttpGet(path);
// execute the method
HttpResponse response = httpClient.execute(m);
A note on this section:
(X509HostnameVerifier) SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
This tells the SSLSocketFactory to accept the certificate even if the hostname doesn’t match the information from the certificate. Especially useful when testing using self-signed certificates or changing ip-addresses. Note that you shouldn’t, of course, use this in production.