Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Pre-Emptive" Basic Auth for Spring-WS Client

Tags:

spring-ws

I'm trying to use build a simple web service client using Spring-WS and am hitting a wall. The SOAP service I'm attempting to call uses HTTP Basic Authentication for security.

Using the Spring-WS tutorial example, I have configured myWebServiceTemplate to use the HttpComponentsMessageSender with my credentials provided:

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="messageSender">
        <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
            <property name="credentials">
                <bean class="org.apache.http.auth.UsernamePasswordCredentials">
                    <constructor-arg value="john:secret"/>
                </bean>
            </property>
        </bean>
    </property>
    <property name="defaultUri" value="http://example.com/WebService"/>
</bean>

When I try to execute the client, I get the following error:

org.springframework.ws.client.WebServiceTransportException: Authorization Required [401]

My previous (WebServiceTemplate with Basic Auth using HttpComponentsMessageSender and HttpClientBuilder basic auth) searches indicate the problem is that Spring-WS is attempting to first connect to the endpoint without the credentials, which is causing the endpoint to reject the initial connection.

It seems that this is a pretty common issue with web services that still use HTTP Basic Authentication.

My question is how can I get Spring to present the credentials on the initial connection attempt?

I would like to avoid re-implementing the entire framework for something seemingly trivial.

(For reference, the endpoint is an internal web service that I don't have control over, and there's no other option to use HTTP Basic Authentication, regardless of how defunct or insecure one might think it is).

Thanks!

like image 431
CWG Avatar asked Jul 08 '14 15:07

CWG


1 Answers

I assume you have created a client that extends WebServiceGatewaySupport. In this case when defining the client in your Configuration class set the MessageSender there. MessageSender must be configured with Credentials.

@Bean
public ValidateCustomerClient customerClient(Jaxb2Marshaller marshaller, WebServiceMessageSender messageSender){
    ValidateCustomerClient client = new ValidateCustomerClient();
    client.setDefaultUri(DEFAULT_URI);
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    client.setMessageSender(messageSender);//set MessageSender here instead on WebServiceTemplate
    return client;
}

I find that setting the MessageSender with Credentials on the WebServiceTemplate does not keep Credentials when client is invoked thereby causing 401.

While this solution have worked on our case, I would welcome any feedback.

like image 127
aalmero Avatar answered Nov 04 '22 22:11

aalmero