Interacting with SOAP headers using CXF

Sometimes you might want to interact with data being passed over SOAP within the SOAP headers, for example this is a technique used to pass security tokens or user information etc.

CXF comes with quite a few “insertion points” whereby we can insert our code into the workflow of WSDL creation, SOAP calls etc. Here we’ll just look at the specifics of intercepting the SOAP call and extracting the header (ofcourse the reverse can also be implemented, whereby we intercept an outward bound call and insert a SOAP header item, but that’s for the reader to investigate).

I’m only going to cover implementing this in code, but obviously this can also be setup via Spring configuration also.

To add an interceptor to our JaxWsServerFactoryBean, we do the following

JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
// set up the bean, address etc.

org.apache.cxf.endpoint.Server server = factory.create();
server.getEndpoint().getInInterceptors().add(new SoapInterceptor());

Now let’s look at the SoapInterceptor

public class SoapInterceptor extends AbstractSoapInterceptor {
    public static final String SECURITY_TOKEN_ELEMENT = "securityToken";

    public SoapInterceptor() {
        super(Phase.PRE_PROTOCOL);
        addBefore(WSDLGetInterceptor.class.getName());
    }
    
    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        String securityToken = getTokenFromHeader(message);
        // do something with the token, maybe save in a context
    }

    private String getTokenFromHeader(SoapMessage message) {
        String securityToken = null;
        try {
            List<Header> list = message.getHeaders();
            for(Header h : list) {
                if(h.getName().getLocalPart() == SECURITY_TOKEN_ELEMENT) {
                    Element token = (Element)h.getObject();
                    if(token != null) {
                        securityToken = token.getTextContent().toString();
                        break;
                    }
                }
            }
        } catch (RuntimeException e) {
            throw new JAXRPCException("Invalid User", e);
        } catch (Exception e) {
            throw new JAXRPCException("Security Token failure ", e);
        }
        return securityToken;
    }
}