Bob Santos
Bob Santos

Reputation: 55

Spring Integration: Force Webservice Outbound Gateway to Use TLSv1

I'm trying to integrate with an external webservice and it use a certificate with TLS 1.0 protocol.

I've tried setting -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2,SSLv3 but the outbound gateway still uses TLSv1.2. It works correctly if I just limit the option to TLSv1 but I can't do that since I'm integrating to a lot of external services.

How can you set the protocol on the outbound gateway itself?

I tried doing that with this code but I ran to an exception:

SimpleWebServiceOutboundGateway handler = new SimpleWebServiceOutboundGateway(url);
HttpComponentsMessageSender sender = new HttpComponentsMessageSender();
SSLContext sslContext = SSLContext.getDefault();
sslContext.getDefaultSSLParameters().setProtocols(new String[]{"TLSv1"});
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
sender.setHttpClient(httpClient);
handler.setMessageSender(sender);

Exception:

Caused by: org.apache.http.client.ClientProtocolException: null
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at org.springframework.ws.transport.http.HttpComponentsConnection.onSendAfterWrite(HttpComponentsConnection.java:121)
    at org.springframework.ws.transport.AbstractWebServiceConnection.send(AbstractWebServiceConnection.java:48)
    at org.springframework.ws.client.core.WebServiceTemplate.sendRequest(WebServiceTemplate.java:658)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:606)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
    ... 91 common frames omitted
Caused by: org.apache.http.ProtocolException: Content-Length header already present
    at org.apache.http.protocol.RequestContent.process(RequestContent.java:97)
    at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:133)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:182)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    ... 99 common frames omitted

Upvotes: 1

Views: 1269

Answers (1)

Bob Santos
Bob Santos

Reputation: 55

I looked at related documentations for HttpComponentsMessengerSender and found HttpComponentsMessageSender.RemoveSoapHeadersInterceptor

HttpClient HttpRequestInterceptor implementation that removes Content-Length and Transfer-Encoding headers from the request. Necessary, because some SAAJ and other SOAP implementations set these headers themselves, and HttpClient throws an exception if they have been set.

The solution is to add it to the interceptors of HttpComponentsMessengerSender.

The final version of the sender is:

SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1").build();
CloseableHttpClient httpClient = HttpClients.custom()
            .setSSLContext(sslContext)
            .addInterceptorFirst(new 
HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
            .build();

HttpComponentsMessageSender sender = new HttpComponentsMessageSender(httpClient);

Upvotes: 2

Related Questions