我有两个基于Spring的Web应用A和B,分别在两台不同的机器上。
我想从Web应用A向Web应用B发起HTTPS调用,但是,我在机器B上使用了自签名证书。因此我的HTTPS请求失败了。
在Spring中使用RestTemplate时,如何禁用HTTPS证书验证?我想要禁用验证,因为Web应用A和B都在内部网络中,但是数据传输必须通过HTTPS进行。
我有两个基于Spring的Web应用A和B,分别在两台不同的机器上。
我想从Web应用A向Web应用B发起HTTPS调用,但是,我在机器B上使用了自签名证书。因此我的HTTPS请求失败了。
在Spring中使用RestTemplate时,如何禁用HTTPS证书验证?我想要禁用验证,因为Web应用A和B都在内部网络中,但是数据传输必须通过HTTPS进行。
@Bean
public RestTemplate restTemplate() throws Exception {
SSLContext sslContext = new SSLContextBuilder()
.loadKeyMaterial(keyStore, keyStorePassword.toCharArray(), keyStorePassword.toCharArray())
.loadTrustMaterial(trustStore, trustStorePassword.toCharArray(), (cert, authType) -> sslTrustStrategy)
.build();
HostnameVerifier hostnameVerifier = sslTrustStrategy ? new NoopHostnameVerifier() :
SSLConnectionSocketFactory.getDefaultHostnameVerifier();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
HttpComponentsClientHttpRequestFactory httpComponentsHttpClientFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(httpComponentsHttpClientFactory);
return restTemplate;
}
*HttpsURLConnection.setDefaultHostnameVerifier(
//SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
// * @deprecated (4.4) Use {@link org.apache.http.conn.ssl.NoopHostnameVerifier}
new NoopHostnameVerifier()
);*
fun getClientHttpRequestFactory(): ClientHttpRequestFactory {
val timeout = envTimeout.toInt()
val config = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout)
.build()
val acceptingTrustStrategy = TrustStrategy { chain: Array<X509Certificate?>?, authType: String? -> true }
val sslContext: SSLContext = SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build()
val csf = SSLConnectionSocketFactory(sslContext)
val client = HttpClientBuilder
.create()
.setDefaultRequestConfig(config)
.setSSLSocketFactory(csf)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build()
return HttpComponentsClientHttpRequestFactory(client)
}
@Bean
fun getRestTemplate(): RestTemplate {
return RestTemplate(getClientHttpRequestFactory())
}
package com.example.teocodownloader;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
public class Example {
public static void main(String[] args) {
CloseableHttpClient httpClient
= HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestClientConfiguration {
@Primary
@Bean("restClient")
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
final var restTemplate = new RestTemplate();
ClientHttpRequestFactory requestFactory = disableSSlHttpClient5();
restTemplate.setRequestFactory(requestFactory);
return restTemplate;
}
private HttpComponentsClientHttpRequestFactory disableSSlHttpClient5()
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial((X509Certificate[] certificateChain, String authType) -> true) // <--- accepts each certificate
.build();
Registry<ConnectionSocketFactory> socketRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(URIScheme.HTTPS.getId(), new SSLConnectionSocketFactory(sslContext))
.register(URIScheme.HTTP.getId(), new PlainConnectionSocketFactory())
.build();
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(new PoolingHttpClientConnectionManager(socketRegistry))
.setConnectionManagerShared(true)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
}
这是关于Spring 3.1.2的答案
依赖
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
代码
@Bean
public RestTemplate getRestTemplate() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(csf).build();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;