springboot中使用restTemplate进行https证书校验请求
【摘要】 一、背景由于安全要求,要求针对不可信的请求都需要使用https请求,访问https请求时也需要去校验证书,防止中间人攻击。 但是实现各种各样,除了restTemplate还有启动调用服务的函数,校验方式又不一样,查询了很多资料,基本都是如何忽略https的证书校验,所以针对restTemplate做一个简单的总结,如何配置保证证书的安全校验。二、代码详情import org.apache.h...
一、背景
由于安全要求,要求针对不可信的请求都需要使用https请求,访问https请求时也需要去校验证书,防止中间人攻击。 但是实现各种各样,除了restTemplate还有启动调用服务的函数,校验方式又不一样,查询了很多资料,基本都是如何忽略https的证书校验,所以针对restTemplate做一个简单的总结,如何配置保证证书的安全校验。
二、代码详情
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
@Configuration
public class RestTemplateOfCerConfig {
/**
* resources 目录下证书路径
* cerPath = "classpath:/keystore/client_trust.keystore";
*/
@Value("${cer-path}")
private String cerPath;
/**
* 使用"keytool"命令导入证书时输入的密码
* cerPwd = "111111";
*/
@Value("${cer-pwd}")
private String cerPwd;
@Bean(name = "cerRestTemplate") // 注册restTemplate对象
public RestTemplate hwRestTemplate(HttpComponentsClientHttpRequestFactory cerHttpsFactory) {
RestTemplate restTemplate = new RestTemplate(cerHttpsFactory);
return restTemplate;
}
@Bean(name = "cerHttpsFactory")// 注册restTemplate工厂对象
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() throws Exception {
CloseableHttpClient httpClient = createCloseableHttpClient();
HttpComponentsClientHttpRequestFactory httpsFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
httpsFactory.setReadTimeout(2000);
httpsFactory.setConnectTimeout(2000);
return httpsFactory;
}
/**
* https协议证书认证
*
* @return
* @throws Exception
*/
private CloseableHttpClient createCloseableHttpClient() throws Exception {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(resourceLoader(cerPath), cerPwd.toCharArray());
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()).build();
// 这里的通信协议要根据使用的JDK版本来适配
SSLConnectionSocketFactory sslfactory = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
CloseableHttpClient closeableHttpClient = httpClientBuilder.setSSLSocketFactory(sslfactory).build();
return closeableHttpClient;
}
/**
* 读取文件信息
*
* @param fileFullPath
* @return
* @throws IOException
*/
public InputStream resourceLoader(String fileFullPath) throws IOException {
ResourceLoader resourceLoader = new DefaultResourceLoader();
return resourceLoader.getResource(fileFullPath).getInputStream();
}
}
以上便是针对restTemplate的配置的一个简单介绍,仅做参考。
第二种,差不多的,只是一个函数。
@Bean
public RestTemplate restTemplate() {
SSLContext sslContext;
try (InputStream inputStream = Files.newInputStream(new File(keyStore).toPath())) {
// 加载根证书
KeyStore trustStore = KeyStore.getInstance(keyStoreType);
trustStore.load(inputStream, keyStorePassword.toCharArray());
// 设置协议
sslContext = new SSLContextBuilder().setProtocol("TLSv1.2").loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
} catch (Exception e) {
e.printStackTrace();
}
// 设置校验的类型
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(120000).setSocketTimeout(120000).build()).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}
原文参考:https://blog.csdn.net/qq_40784783/article/details/115539324
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)