Search code examples
javaweb-servicessoapjax-wsclient-certificates

How to specify the client certificate on a JAX-WS client and client certificate authentication


I'm programming a JAX-WS client in Java. The access to the WebService is protected with a client certificate. I know the client certificate is right because I can get the WSDL in Firefox only if the client certificate was imported (in Firefox).

But I have problems to write my java application which should use the WebService. What I have do is following:

  MyOwnService svc = new MyOwnService(getServerURL(), MYOWNSERVICE_QNAME);
...
...
private URL getServerURL() throws IOException {
  URL url = new URL((String) cfg.get(ConfigData.SERVER_URL));

  HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

  try {
    con.setSSLSocketFactory(getFactory(new File("/etc/pki/wildfly/client.keystore"), "123456"));
  } catch (Exception exc) {
    throw new IOException("Client certificate error!", exc);
  }

  return url;
}

private SSLSocketFactory getFactory(File pKeyFile, String pKeyPassword ) 
  throws ... {

  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
  KeyStore keyStore = KeyStore.getInstance("PKCS12");

  InputStream keyInput = new FileInputStream(pKeyFile);
  keyStore.load(keyInput, pKeyPassword.toCharArray());
  keyInput.close();

  keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

  SSLContext context = SSLContext.getInstance("TLS");
  context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

  return context.getSocketFactory();
}

But this didn't work. If I run this I get following exception in the MyOwnService constructor

java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.

How is the correct way to implemnting a JAX-WS client which supports client certification?


Solution

  • Forget my code above. Seem's that the only thing you must do is to specify the keystore as environment variables like:

    -Djavax.net.ssl.keyStore=/etc/pki/wildfly/client.keystore -Djavax.net.ssl.keyStorePassword=123456
    

    If I do so and specifying the correct keystore it works. If I specify an invalid keystore file (which contains a other/wrong certificate/key) it don't works :) .

    But I'm not sure how Java gets the right key/cert from the keystore if the keystore contains more as one PrivateKeyEntry. Specifying javax.net.ssl.keyStoreAlias will be have no effect. May be Java tries the PrivateKeyEntrys until the right one was found ...

    However: The only thing to do is to specify the right keystore as environment variable.