Question

With spring-integration I would like to call an outbound-gateway with an Basic Authentication. I have something like this :

<int-http:inbound-gateway id="versionRequestGateway" 
    supported-methods="POST" request-channel="requestVersionChannel"
    reply-channel="requestTransformerVersionChannel" 
    path="/consultersite" reply-timeout="10000" request-payload-type="java.lang.String">
</int-http:inbound-gateway>
<int-http:outbound-gateway order="1" request-channel="requestVersionChannel"
    url-expression="@urlExpressionGateway.getUrlFor(payload) + '/consultersite'"
    reply-channel="responseVersionChannel"
    http-method="POST" 
    expected-response-type="java.lang.String" >
</int-http:outbound-gateway>

The URL of outbound-gateway is dynamic.

I decide to use rest-template attribute on the outbound-gateway, with this :

<bean id="httpClientParams" class="org.apache.commons.httpclient.params.HttpClientParams">
    <property name="authenticationPreemptive" value="true"/>
    <property name="connectionManagerClass" value="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/>
</bean>
<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
    <constructor-arg ref="httpClientParams"/>
</bean>
<bean id="httpClientFactory" class="org.springframework.http.client.CommonsClientHttpRequestFactory">
    <constructor-arg ref="httpClient"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
    <constructor-arg ref="httpClientFactory"/>
</bean>

It's work when I inject an UsernamePasswordCredentials in an ApplicationListener after spring application context is loaded.

HttpClient client = ctx.getBean("httpClient", HttpClient.class);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("username", "password");
client.getState().setCredentials(AuthScope.ANY, credentials);

But according the url of outbound-gateway, username and password are different. How can I do to use the good username/password according the url outbound-gateway ?

It was necessary to implement my own BasicSecureSimpleClientHttpRequestFactory extends SimpleClientHttpRequestFactory to map information Credentials according to the URL of connection. Hope an implementation Spring will be available one day ... Thanks.

Was it helpful?

Solution

Do not type any Java code you can use a combination of Spring WS HttpComponentsMessageSender and Spring WEB HttpComponentsClientHttpRequestFactory:

<bean id="httpComponentsMessageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
    <property name="credentials">
        <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
            <constructor-arg value="userName"/>
            <constructor-arg value="password"/>
        </bean>
    </property>
</bean>

<bean id="clientHttpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
    <property name="httpClient" value="#{httpComponentsMessageSender.httpClient}"/>
</bean>

<int-http:outbound-gateway url-expression="@urlExpressionGateway.getUrlFor(payload) + '/consultersite'"
                           request-factory="clientHttpRequestFactory"/>

I can believe, that my answer might not be full for your case. However I hope it can help a bit.

Maybe there is need to implement your own HttpComponentsClientHttpRequestFactory#createRequest to authenticate at runtime and do this:

method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true));

Take a look into source code of HttpMethodDirector#authenticateHost

OTHER TIPS

you should use org.apache.http.auth.UsernamePasswordCredentials implementation instead of org.apache.commons.httpclient.UsernamePasswordCredentials

<beans:bean id="httpComponentsMessageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
        <beans:property name="credentials">
            <beans:bean class="org.apache.http.auth.UsernamePasswordCredentials">
                <beans:constructor-arg value="user"/>
                <beans:constructor-arg value="password"/>
            </beans:bean>
        </beans:property>
    </beans:bean>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top