5 Replies Latest reply on Oct 24, 2008 5:10 PM by Mattias Öhrn

    Full control of client and server certificates with a JBossW

    Mattias Öhrn Newbie

      I want to invoke a web service over https with client certificate authentication. The problem is that I need to control exactly which client certificate/key is used and what server certificates to trust per invocation. All examples i can find involves setting global properties and that is not good enough for me.

      My application is an EJB3 application running in in JBoss AS 4.2.2 with JBossWS as JAX-WS provider. In JAX-WS 2.1 RI there is a simple way of doing what I want by setting a passing a SSLSocketFactory in the RequestContext of the SEI proxy (see my example below).

      package org.acme.ejb3;
      import java.net.Socket;
      import java.security.Principal;
      import java.security.PrivateKey;
      import java.security.SecureRandom;
      import java.security.cert.CertificateException;
      import java.security.cert.X509Certificate;
      import java.util.Map;
      import javax.ejb.Remote;
      import javax.ejb.Stateless;import javax.net.ssl.KeyManager;
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.TrustManager;
      import javax.net.ssl.X509KeyManager;
      import javax.net.ssl.X509TrustManager;
      import javax.xml.ws.BindingProvider;
      import javax.xml.ws.WebServiceRef;
      public class MyTestClientBean implements MyTestClient {
       private SomeWebServicePortType sei;
       public String saySometing(String message, String endpointAddress,
       X509Certificate[] clientCertChain, PrivateKey clientKey,
       X509Certificate trustedCaCert) throws Exception {
       Map<String, Object> reqCtx = ((BindingProvider)sei).getRequestContext();
       // Standard JAX-WS method to set the endpoint address.
       reqCtx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
       // My custom key manager
       KeyManager[] keyMgrs = { new MyClientKeyManager(clientCertChain, clientKey) };
       // My custom trust manager
       TrustManager[] trustMgrs = { new MyClientTrustManager(trustedCaCert) };
       // Get an SSL context and initialize it with my custom key and trust managers.
       SSLContext sslCtx = SSLContext.getInstance("TLS");
       sslCtx.init(keyMgrs, trustMgrs, SecureRandom.getInstance("SHA1PRNG"));
       // Use the JAX-WS 2.1 RI specific property to ensure that
       // my custom managers are used.
       // Finally invoke the web service.
       return sei.saySometing(message);
      class MyClientKeyManager implements X509KeyManager {
       private X509Certificate[] clientCertChain;
       private PrivateKey clientKey;
       public MyClientKeyManager(X509Certificate[] clientCertChain,
       PrivateKey clientKey) {
       this.clientCertChain = clientCertChain;
       this.clientKey = clientKey;
       // Here comes my custom KeyManager implementation
      class MyClientTrustManager implements X509TrustManager {
       private X509Certificate trustedCaCertificate;
       public MyClientTrustManager(X509Certificate trustedCaCertificate) {
       this.trustedCaCertificate = trustedCaCertificate;
       // Here comes my custom TrustManager implementation

      Is there any way of doing something similar in JBossWS?