RestTemplate绕过SSL证书校验
RestTemplate绕过SSL证书校验
·
上一篇文章已经通过配置RestTemplate,完成了后台客户端以https方式对服务端接口的访问。本篇作为补充说明,介绍一下如果在没有证书的情况下,绕过SSL证书的校验。
配置步骤如下:
一. 从JDK证书管理库删除原证书(非必须),如果未导入过证书请忽略此步
查看证书命令:keytool -list -storepass changeit -keystore "C:/Program Files/Java/jdk1.8.0_131/jre/lib/security/cacerts"|findstr testhttps
删除证书命令:keytool -delete -alias testhttps -storepass changeit -keystore "C:/Program Files/Java/jdk1.8.0_131/jre/lib/security/cacerts"
二. 添加相应代码
1. 忽略ssl证书校验类
import org.apache.http.client.HttpClient;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* 绕过证书
*/
public class IgnoreSSLRequestFactory extends SimpleClientHttpRequestFactory {
public IgnoreSSLRequestFactory(HttpClient httpClient) {
super();
}
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod)
throws IOException {
if (connection instanceof HttpsURLConnection) {
prepareHttpsConnection((HttpsURLConnection) connection);
}
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
super.prepareConnection(connection, httpMethod);
}
private void prepareHttpsConnection(HttpsURLConnection connection) {
connection.setHostnameVerifier(new SkipHostnameVerifier());
try {
connection.setSSLSocketFactory(createSslSocketFactory());
} catch (Exception ex) {
// Ignore
}
}
private SSLSocketFactory createSslSocketFactory() throws Exception {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[]{new SkipX509TrustManager()},
new SecureRandom());
return context.getSocketFactory();
}
private class SkipHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
private static class SkipX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
2. 编写RestTemplate配置类
import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
/**
* restTemplate配置
*/
@Configuration
public class RestTemplateConfig {
/**
* 使用ssl对证书进行验证,需要将证书导出到jdk管理仓库,
* 命令:keytool -import -v -trustcacerts -alias mytest -file "D:/tmp/mytest.cer" -keystore "C:/Program Files/Java/jdk1.8.0_131/jre/lib/security/cacerts"
*/
@Bean("restTemplate")
@Primary
public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new
HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(6 * 1000); //获取连接池连接的超时时间(毫秒)
httpRequestFactory.setConnectTimeout(6 * 1000); //连接上服务器(握手成功)的时间(毫秒)
httpRequestFactory.setReadTimeout(60 * 1000); //返回数据时间(毫秒)
httpRequestFactory.setHttpClient(httpClient());
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
return restTemplate;
}
/**
* 绕过ssl对证书进行验证,无需将证书导出到jdk管理仓库
*/
@Bean("restTemplateIgnoreSSL")
public RestTemplate restTemplateIgnoreSSL() throws NoSuchAlgorithmException, KeyManagementException {
IgnoreSSLRequestFactory requestFactory = new IgnoreSSLRequestFactory(httpClient());
requestFactory.setConnectTimeout(60000); //连接上服务器(握手成功)的时间
requestFactory.setReadTimeout(60000); //返回数据时间
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
@Bean
public HttpClient httpClient() throws KeyManagementException, NoSuchAlgorithmException {
SSLContextBuilder contextBuilder = new SSLContextBuilder();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(contextBuilder.build(), NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", socketFactory).build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
connectionManager.setMaxTotal(200);
connectionManager.setDefaultMaxPerRoute(100);
CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build();
return httpClient;
}
3. 编写Controller 控制类
import com.ssl.demo.entity.UserInfo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
public class UserController {
/**
* 使用https访问接口
*/
@Resource(name = "restTemplate")
private RestTemplate restTemplate;
/**
* 使用https访问接口,并忽略ssl证书验证
*/
@Resource(name = "restTemplateIgnoreSSL")
private RestTemplate restTemplateIgnoreSSL;
@RequestMapping("getUserInfo")
public UserInfo getUserInfo() {
UserInfo data = restTemplate.getForObject("https://localhost:9090/ssl-service/getUserInfo", UserInfo.class);
return data;
}
@RequestMapping("getUserInfoIgnoreSSL")
public UserInfo getUserInfoIgnoreSSL() {
UserInfo data = restTemplateIgnoreSSL.getForObject("https://localhost:9090/ssl-service/getUserInfo", UserInfo.class);
return data;
}
}
四. 验证结果
在浏览器访问:http://localhost:8080/ssl-client/getUserInfoIgnoreSSL
至此完成了忽略SSL验证的配置和验证。
完整示例下载地址(同上一篇文章):
链接:https://pan.baidu.com/s/1xrfxkbnz1bGhhrTKKKhPew
提取码:tyoe
更多推荐
已为社区贡献2条内容
所有评论(0)