How to Call a Secure SOAP Service with WS-Security with JAX-WS

Sample.java

import static java.lang.System.out;

import java.util.List;

import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;

import br.eti.fernandoribeiro.wsclient.sample.SamplePortType;
import br.eti.fernandoribeiro.wsclient.sample.SampleRequest;
import br.eti.fernandoribeiro.wsclient.sample.SampleResponse;
import br.eti.fernandoribeiro.wsclient.sample.SampleService;

public final class Sample {

  public static void main(final String[] args) throws Exception {
    final SampleService service = new SampleService();

    final SamplePortType port = service.getSamplePort();

    final Binding binding = ((BindingProvider) port).getBinding();

    @SuppressWarnings("rawtypes")
    final List<Handler> handlerChain = binding.getHandlerChain();

    handlerChain.add(new SampleSecurityHandler());

    binding.setHandlerChain(handlerChain);

    final SampleResponse res = port.execute(new SampleRequest());

    out.println(res);
  }

}

SampleSecurityHandler.java

import java.util.HashSet;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;

public final class SampleSecurityHandler implements SOAPHandler<SOAPMessageContext> {
  private XWSSProcessor processor = null;

  public SampleSecurityHandler() {

    try {
      final XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();

      processor = factory.createProcessorForSecurityConfiguration(getClass().getResourceAsStream("/META-INF/user-pass-authenticate-client.xml"), new SampleCallbackHandler() /* null if you provide the user name and password in the user-pass-authenticate-client.xml file */);
    } catch (final Exception e) {
      e.printStackTrace();
    }

  }

  public void close(MessageContext messageContext) {
  }

  public Set<QName> getHeaders() {
    final Set<QName> headers = new HashSet<QName>();

    headers.add(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"));

    return headers;
  }

  public boolean handleFault(final SOAPMessageContext messageContext) {
    return false;
  }

  public boolean handleMessage(final SOAPMessageContext messageContext) {

    if ((Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {

      try {
        final ProcessingContext processingContext = processor.createProcessingContext(messageContext.getMessage());

        messageContext.setMessage(processor.secureOutboundMessage(processingContext));

        return true;
      } catch (final Exception e) {
        e.printStackTrace();
      }

    }

    return false;
  }

}

SampleCallbackHandler.java

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;

import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;

public final class SampleCallbackHandler implements CallbackHandler {

  public void handle(final Callback[] callbacks) {

    for (int i = 0; i < callbacks.length; i++) {

      if (callbacks[i] instanceof UsernameCallback) {
        final UsernameCallback cb = (UsernameCallback) callbacks[i];

        cb.setUsername("username");
      } else if (callbacks[i] instanceof PasswordCallback) {
        PasswordCallback cb = (PasswordCallback) callbacks[i];

        cb.setPassword("password");
      }

    }

  }

}[/sourcecode]

<strong>user-pass-authenticate-client.xml</strong>

<?xml version="1.0" encoding="UTF-8"?>
<SecurityConfiguration xmlns="http://java.sun.com/xml/ns/xwss/config">
  <UsernameToken digestPassword="false" /> <!-- you can also provide "user" and "password" -->
</SecurityConfiguration>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s