如何使用 Rest 模板将 TLS1.2 强制执行到 Rest 客户端
How to enforce TLS1.2 to Rest client using Rest Template
我正在通过调用 post 方法使用 Spring3.0 restTemplate 使用 json 网络服务。
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<Object> entity = new HttpEntity<Object>(requestAsString, headers);
postForObject = restTemplate.postForObject(url, entity, responseClass );
我们的应用程序部署在 WAS 服务器中,并尝试通过使用 TLS1.0 创建套接字连接来连接生产者。但是现在producer只支持TLS1.1和TLS1.2
如何强制 restTempate 使用 TLS1.1 或 TLS 1.2。
通常对于 apache httpclient 代码,创建自定义 ProtocolSocketFactory 并覆盖 createSocket 方法。但是,在 RestTemplate 的情况下,如何实现相同。
您可以将 RestTemplate 配置为使用自定义 ClientHttpRequestFactory
。特别是(因为您使用的是 Spring 3.0),有一个 CommonsClientHttpRequestFactory。这将使您能够详细配置公共 HTTP,并且您的 RestTemplate 将使用它来执行其请求。
请注意 classes 的实际实现在更高版本的 Spring 中发生了变化(如果您仍在使用 3.0,则您真的应该考虑更新)。从 3.1 开始,实现 class 被称为 HttpComponentsClientHttpRequestFactory
.
Spring > 3.1:
import javax.net.ssl.SSLContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null, null, null);
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(context)
.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(factory);
.....
@abhishekhp 如果您的问题仍然存在。
RestTemplate restTemplate = new RestTemplate();
DefaultHttpClient httpClient = new DefaultHttpClient();
// We're going to try and load and enable TLS version 1.2 standard communication context from JSSE Providers
// This is enabled only for download media Mirakl as some merchants don't accept communication with TLS versions prior to 1.1
try {
SSLContext context;
context = SSLContext.getInstance("TLSv1.2");
context.init(null, null, null);
SSLSocketFactory ssf = new SSLSocketFactory(context);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
sr.register(new Scheme("https", 443, ssf));
} catch (NoSuchAlgorithmException | KeyManagementException e) {
LOGGER.warn("Could not load the TLS version 1.2 due to => ", e);
}
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
如果您想设置多个有效的 TLS 版本,请使用 SSLConnectionSocketFactory
。例如,如果您想支持 TLSv1.2 和 TLSv1.3:
public HttpClient getHttpClient() {
final var sslContext = SSLContext.getDefault();
// TLSv1.2 or TLSv1.3
final var sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2","TLSv1.3"},
null, javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier());
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}
并将其与 RestTemplate
组合起来,如下所示:
@Bean
public RestTemplate restTemplate() {
final var factory = new HttpComponentsClientHttpRequestFactory(getHttpClient());
return new RestTemplate(factory);
}
我正在通过调用 post 方法使用 Spring3.0 restTemplate 使用 json 网络服务。
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<Object> entity = new HttpEntity<Object>(requestAsString, headers);
postForObject = restTemplate.postForObject(url, entity, responseClass );
我们的应用程序部署在 WAS 服务器中,并尝试通过使用 TLS1.0 创建套接字连接来连接生产者。但是现在producer只支持TLS1.1和TLS1.2
如何强制 restTempate 使用 TLS1.1 或 TLS 1.2。
通常对于 apache httpclient 代码,创建自定义 ProtocolSocketFactory 并覆盖 createSocket 方法。但是,在 RestTemplate 的情况下,如何实现相同。
您可以将 RestTemplate 配置为使用自定义 ClientHttpRequestFactory
。特别是(因为您使用的是 Spring 3.0),有一个 CommonsClientHttpRequestFactory。这将使您能够详细配置公共 HTTP,并且您的 RestTemplate 将使用它来执行其请求。
请注意 classes 的实际实现在更高版本的 Spring 中发生了变化(如果您仍在使用 3.0,则您真的应该考虑更新)。从 3.1 开始,实现 class 被称为 HttpComponentsClientHttpRequestFactory
.
Spring > 3.1:
import javax.net.ssl.SSLContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null, null, null);
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(context)
.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(factory);
.....
@abhishekhp 如果您的问题仍然存在。
RestTemplate restTemplate = new RestTemplate();
DefaultHttpClient httpClient = new DefaultHttpClient();
// We're going to try and load and enable TLS version 1.2 standard communication context from JSSE Providers
// This is enabled only for download media Mirakl as some merchants don't accept communication with TLS versions prior to 1.1
try {
SSLContext context;
context = SSLContext.getInstance("TLSv1.2");
context.init(null, null, null);
SSLSocketFactory ssf = new SSLSocketFactory(context);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
sr.register(new Scheme("https", 443, ssf));
} catch (NoSuchAlgorithmException | KeyManagementException e) {
LOGGER.warn("Could not load the TLS version 1.2 due to => ", e);
}
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
如果您想设置多个有效的 TLS 版本,请使用 SSLConnectionSocketFactory
。例如,如果您想支持 TLSv1.2 和 TLSv1.3:
public HttpClient getHttpClient() {
final var sslContext = SSLContext.getDefault();
// TLSv1.2 or TLSv1.3
final var sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2","TLSv1.3"},
null, javax.net.ssl.HttpsURLConnection.getDefaultHostnameVerifier());
return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
}
并将其与 RestTemplate
组合起来,如下所示:
@Bean
public RestTemplate restTemplate() {
final var factory = new HttpComponentsClientHttpRequestFactory(getHttpClient());
return new RestTemplate(factory);
}