Spring集成:强制Webservice出站网关使用TLSv1

时间:2017-11-21 09:00:58

标签: java spring web-services spring-integration

我尝试与外部Web服务集成,并使用带有TLS 1.0协议的证书。

我已尝试设置-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2,SSLv3,但出站网关仍使用TLSv1.2。如果我只是将选项限制为TLSv1,它可以正常工作,但我无法做到这一点,因为我正在集成到许多外部服务中。

如何在出站网关本身设置协议?

我尝试使用此代码执行此操作,但我遇到了异常:

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);

例外:

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

1 个答案:

答案 0 :(得分:2)

我查看了HttpComponentsMessengerSender的相关文档,发现HttpComponentsMessageSender.RemoveSoapHeadersInterceptor

  

HttpClient HttpRequestInterceptor实现,用于从请求中删除Content-Length和Transfer-Encoding标头。必要的,因为一些SAAJ和其他SOAP实现本身设置了这些头文件,并且如果已经设置了HttpClient则抛出异常。

解决方案是将其添加到HttpComponentsMessengerSender

的拦截器中

发件人的最终版本是:

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

HttpComponentsMessageSender sender = new HttpComponentsMessageSender(httpClient);