cxf webclient使用TLSV1调用api

时间:2018-01-03 05:38:34

标签: java rest web-services ssl cxf

我需要调用和休息由第三方托管的端点。他们的服务仅支持TLSv1,目前不支持任何新版本。我尝试将webclient配置设置为将其用于TLSV1,如下所示。

WebClient client = WebClient
    .create(serviceEndPoint,
        Collections.singletonList(new JacksonJsonProvider()));
client.path(requestTokenService);

HTTPConduit conduit =
    (HTTPConduit) WebClient.getConfig(client).getConduit();
HTTPClientPolicy policy = conduit.getClient();
try {
  SSLContext sslContext = SSLContext.getInstance("TLSv1");
  sslContext.init(null, null, null);
  TLSClientParameters tlsParams = new TLSClientParameters();
  tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
  tlsParams.setSecureSocketProtocol("TLSv1");
  conduit.setTlsClientParameters(tlsParams);
  logger.info("TLS set to 1.0");
} catch (NoSuchAlgorithmException e) {
  logger.error("Setting the tls failed with  NoSuchAlgorithmException ["+e.getMessage()+"]");
} catch (KeyManagementException e) {
  logger.error("Setting the tls failed with KeyManagementException ["+e.getMessage()+"]");
}
policy.setProxyServer(proxyUrl);
policy.setProxyServerPort(proxyPort);

ClientConfiguration config = WebClient.getConfig(client);

config.getInInterceptors().add(new LoggingInInterceptor());
config.getOutInterceptors().add(new LoggingOutInterceptor());
Response response = client.get();

调用get方法时出现以下错误。

  

2018-01-03 05:30:19,207 [eb46095f-71d9-4a3f-98c3-beec8d97dbf5]错误   [服务类]    - 持久失败并出现错误[javax.net.ssl.SSLHandshakeException:SSLHandshakeException调用   HTTPS:abc.com/thepath:   服务器选择了TLSv1,但未启用该协议版本   由客户支持。]

这里有关于如何在此连接上启用TLSv1的帮助。

1 个答案:

答案 0 :(得分:1)

请参阅Configure Oracle's JDK and JRE Cryptography Algorithms,标题为 如何更改客户端协议版本 的部分。

相关文字是:

有几种选项可用于更改JDK中的默认客户端TLS协议版本。

选项1.使用“jdk.tls.client.protocols”系统属性

此属性在7u95中被引入JDK 7,在6u121中被引入JDK 6。

要在客户端上启用特定的TLS协议,请在引号内的逗号分隔列表中指定它们;然后在客户端上禁用所有其他支持的协议。例如,如果此属性的值为“TLSv1.1,TLSv1.2”,则在客户端上启用客户端上TLSv1.1和TLSv1.2的默认协议设置,而SSLv3,TLSv1和SSLv2Hello为在客户端禁用。

// Set the client default protocol versions to TLS 1.0, 1.1 and 1.2.
$ java -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" myApp

// Set the client default protocol version to TLS 1.0.
$ java -Djdk.tls.client.protocols="TLSv1" myApp

请注意,JDK中使用的标准TLS协议版本名称是SSLv3,TLSv1,TLSv1.1和TLSv1.2。

选项2.使用SSLContext设置TLS版本

“TLSv1.2”协议的SSLContext支持TLS 1.2。例如:

// Get SSLContext instance for "TLSv1.2".
SSLContext context = SSLContext.getInstance("TLSv1.2");

// Create SSLEngine object that enables TLS version 1.2.
SSLEngine sslEngine = context.createSSLEngine("www.example.com", 443);

或者

// Create SSLSocket object that enables TLS version 1.2.
SSLSocketFactory socketFac = context.getSocketFactory();
SSLSocekt sslSocket = (SSLSocekt)socketFac.createSocket("www.example.com", 443);

An SSLContext with "TLSv1" protocol supports TLS versions up to TLS 1.0 (no TLS 1.1 and 1.2).
An SSLContext created with "TLSv1.1" supports versions up to TLS 1.1 (no TLS 1.2).
// Get SSLContext instance that supports TLS versions up to TLS 1.0.
SSLContext context = SSLContext.getInstance("TLSv1");

选项3.使用SSLSocket / SSLEngine.setEnabledProtocols()API

应用程序可以在SSLSocket / SSLEngine对象中显式设置启用的协议。例如:

// Enable TLS 1.0, 1.1 and 1.2 in an SSLSocket object.
sslSocket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});

// Enable TLS 1.0, 1.1 and 1.2 in an SSLEngine object.
sslEngine.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});

或者

// Enable TLS 1.0 only in an SSLSocket object.
sslSocket.setEnabledProtocols(new String[] {"TLSv1"});

// Enable TLS 1.0 only in an SSLEngine object.
sslEngine.setEnabledProtocols(new String[] {"TLSv1"});

选项4.使用SSLParameters.setProtocols()API

应用程序可以在SSLParameters对象中设置协议,然后通过SSLSocket.setSSLParameters()和SSLEngine.setSSLParameters()方法将其应用于连接。例如:

// Set TLS 1.0, 1.1 and 1.2 in an SSLParameters object.
sslParameters.setProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});

或者

// Set TLS 1.0 only in an SSLParameters object.
sslParameters.setProtocols(new String[] {"TLSv1"});

// Apply the parameters to an SSLSocket object.
sslSocket.setSSLParameters(sslParameters);

// Apply the parameters to an SSLEngine object.
sslEngine.setSSLParameters(sslParameters);

对于客户端应用程序,管理员可能必须从默认启用的协议列表中删除TLS 1.1或TLS 1.2,以解决服务器端的TLS版本不容忍问题。