Spring WS and basic authentication

Today I had to integrate against a web service that required basic authentication in order to use the service. One of my colleagues had started out writing a Spring WebService client against the service. Midway through the task, I was asked to finish off the task as he had to prioritize some urgent production issues. After some initial set up trouble I was ready to test the service….

The client was implemented as a bean extending the WebServiceTemplate of the Spring WS API and it correctly used a CommonsHttpMessageSender where authentication can be set by injecting a Credentials instance (f.ex a UserNamePasswordCredentials).

Everything looked sweet, but when we tested the service we received a 401 the following exception

org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]

We found the answer on the Spring Forum, it turns out that for basic authentication our bean that extends the WebServiceTemplate needs to override the afterPropertiesSet() method and call the afterPropertiesSet() of the CommonsHttpMessageSender. Arjen Poutsma writes:

“No bug , but you need to call afterPropertiesSet() on the CommonsHttpMessageSender. This sets the credentials on the client. Invoking afterPropertiesSet() is automatically done by the Spring container, so if you create a bean definition for the message sender, and inject it into the web service template, this is all taken care off.”

Apparently, the spring container handles this for us when we have overridden the afterPropertiesSet().

So, if we name our spring bean HttpAuthenticationWebServiceTemplate our spring config will look like this:

<bean id="basicAuthenticationTemplate" class="no.netcom.ipl.adaptertemplate.HttpAuthenticationWebServiceTemplate">
        <property name="defaultUri" value="${address}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <property name="marshaller" ref="jaxb2Marshaller"/>
    </bean>

And our java class needs to have the afterPropertiesSet() method implemented (along with setters for the properties defined in the config, but this is left out for brevity)

public class HttpAuthenticationWebServiceTemplate extends WebServiceTemplate {

    private String username = null;
    private String password = null;
    protected CommonsHttpMessageSender messageSender;

    public HttpAuthenticationWebServiceTemplate() {
        super();
        messageSender = (CommonsHttpMessageSender) super.getMessageSenders()[0];
    }

    ...

    @Override
    public void afterPropertiesSet(){
        super.afterPropertiesSet();
        try{
            messageSender.afterPropertiesSet();
        } catch (Exception ex){
            throw new RuntimeException("Unable to configure HttpAuthenticationWebServiceTemplate ", ex);
        }
    }

}

When we test this code we don’t get the 401 back from the server. Instead, I got a 403 – Forbidden. But hey, that´s the life for a software developer, there´s always a new problem waiting around the next corner.


2 Responses to “Spring WS and basic authentication”

  1. Serge Pagop Says:

    I alos now trying to find a solution, but without success. If you get something hoe to solve that let us know with another blog.

    Thanks.

  2. ketiljensen Says:

    When you say

    “If you get something how to solve that let us know…”

    are you then referring to my last statement:

    “When we test this code we don’t get the 401 back from the server. Instead, I got a 403 ….”

    Or?

Leave a Reply