springboot中使用restTemplate进行https证书校验请求

举报
object 发表于 2024/08/28 14:42:31 2024/08/28
【摘要】 一、背景由于安全要求,要求针对不可信的请求都需要使用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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。