Tag Archives: CXF

Getting access to SOAP Headers from an Apache CXF service implementation

For one project I was working on, I needed to get access to the SOAP headers of web service call. I am using the Apache CXF services stack. There were quite a few threads on how to get access to SOAP headers from an interceptor. In my case, I needed the contents of the header inside the implementation.

wsdl2java does have the ability to create a java service class that provides access to the headers using the -exsh option. This was not an option for me since even with this flag on, the headers were not added to the service calls. I think it was how the WSDL I had was designed. This meant that I needed to do the work of pulling out the headers myself.

The SOAP headers can be retrieved from the JAX-WS SOAPMessageContext the easiest. Getting access to this was not trivial. I added the resource annotation to get access to the WebServiceContext. Unfortunately the MessageContext this gave me was not a SOAPMessageContext and provided no way to access the SOAP headers.

After looking through the code for the SoapMessage CXF class, I found how it gets the headers out of the Message. I came up with the following to access the headers from my implementation class:

private WebServiceContext context;

private List<Header> getHeaders() {
    MessageContext messageContext = context.getMessageContext();
    if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
        return null;
    Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
    List<Header> headers = CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
    return headers;

This provides all of the headers available. To get the specific one I needed using JAXB I added the following to my code:

List<Header> headers = getHeaders();
if (headers != null) {
    for (Header h: headers) {
        Object o = h.getObject();
        // Unwrap the node using JAXB
        if (o instanceof Node) {
            o = getJaxb().createUnmarshaller().unmarshal((Node) o);
        if (o instanceof DesiredHeaderType) {
            // Do whatever is required with the header object instance

This way of accessing the headers turns out to be much simpler than writing an interceptor and trying to stuff the results of that into the request.

HTTP Basic Authentication with Apache CXF Revisited

I receive a lot of traffic to my post about HTTP Basic Authentication in Apache CXF. I decided to do a followup to that post to address some of the comments.

I have never tried to use this with Mule but if someone has, please let me know so I can update this post.

I have uploaded the Java code for the BasicAuthAuthorizationInterceptor class. There are a few changes over the original version. This one includes a Map of authorized users and their corresponding passwords. I believe the original example I created was for Apache CXF 2.0. This version works with Apache CXF 2.1.1.

In the original post, I also did not include a sample of how to use this code in a real application. The following section shows a sample of how to define the security interceptor and enable it on a simple endpoint.

<beans xmlns="http://www.springframework.org/schema/beans"
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <bean id="securityInterceptor" class="BasicAuthAuthorizationInterceptor">
      <property name="users"> 
          <entry key="username" value="password"/>

    <bean id="service" class="sample.Service"/>
        <ref bean="securityInterceptor"/>

Apache CXF with HTTP Basic Authentication

Apache CXF is a great library for providing web services from Java. Their integration with the spring framework is the best of any web services library I have seen. But when it comes to documentation, they are a bit lacking in a few areas. Some tasks that you would think would be part of the framework are simply not provided.

There are two approaches to providing security for Web Services. You can secure the protocol itself (HTTP based security) or you can secure the web services call itself (the actual soap message). The new web services standard around security have opted to take the second approach. Web services and SOAP are designed to be separate from the protocol. The WS-Security specifications deal with securing the SOAP packet itself rather than relying on security provided by the underlying protocol (in many cases HTTP).

Apache CXF provides a WS-Security implementation for handling security and authentication for web services. They also provide a mechanism for setting up HTTPs to provide a secured HTTP connection. The one thing they do not provide is a mechanism to authenticate over HTTP. If you have the luxury to use WS-Security then that is not a problem. For a project I was working on, I needed to provide a web service older clients could access that may not know about WS-Security. The solution was to use HTTP Basic Authentication.

Apache CXF provides access to the AuthorizationPolicy from any message. This gives access to the authentication information used for HTTP. The approach I took was to create a CXF interceptor to intercept the message and check this information for HTTP Basic Authentication parameters. If an error occurs then a SOAP fault is thrown.

The problem with this approach was that a fault is returned to the client as an HTTP 500 response code. What we really want here is to use the 401/403 mechanism as a true web server would for HTTP based authentation. I found the following article on the CXF mailing lists that explained how to set some of that up.


I modified that code provide an CXF interceptor that provides HTTP Basic Authentication. When a message is received the HTTP headers are checked. If no user/password is provided, a 401 is returned. This indicates to the client the HTTP authentication is required. If the user/password is invalid, a 403 is returned indicating that this username/password is forbidden to access the service.

Here is an excerpt from the code. I took out some of the implementation details and left the basic “meat” of how to do this from CXF.

public class BasicAuthAuthorizationInterceptor extends 
        SoapHeaderInterceptor {
    private Map<String,String users;
    protected Logger log = Logger.getLogger(getClass());
    @Override public void handleMessage(Message message) 
            throws Fault {
        // This is set by CXF
        AuthorizationPolicy policy = message.get(
        // If the policy is not set, the user did not specify
        // credentials. A 401 is sent to the client to indicate
        // that authentication is required
        if (policy == null) {
        // Verify the password
        String realPassword = getAcualPassword(
        if (realPassword == null || 
                !realPassword.equals(policy.getPassword())) {
            log.warn("Invalid username or password for user: " 
                + policy.getUserName());
    private void sendErrorResponse(Message message, 
            int responseCode) {
        Message outMessage = getOutMessage(message);
        // Set the response headers
        Map responseHeaders = message.get(
        if (responseHeaders != null) {
                Arrays.asList(new String[]{"Basic realm=realm"}));
                Arrays.asList(new String[]{"0"}));
        try {
        } catch (IOException e) {
            log.warn(e.getMessage(), e);
    private Message getOutMessage(Message inMessage) {
        Exchange exchange = inMessage.getExchange();
        Message outMessage = exchange.getOutMessage();
        if (outMessage == null) {
            Endpoint endpoint = exchange.get(Endpoint.class);
            outMessage = endpoint.getBinding().createMessage();
        return outMessage;
    private Conduit getConduit(Message inMessage) 
            throws IOException {
        Exchange exchange = inMessage.getExchange();
        EndpointReferenceType target = exchange.get(
        Conduit conduit =
            inMessage, null, target);
        return conduit;
    private void close(Message outMessage) 
            throws IOException {
        OutputStream os = outMessage.getContent(