springboot 请求https的私有证书验证

一、方案描述

我这里采用RestTemplate的方式调用https请求,请求第三方接口获取数据,证书由第三方私自签发的证书,我们构建的是一个springboot的API项目。

1.pom文件引入jar

java 复制代码
<dependencies>
     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Apache HttpClient - Used to request HTTP resources over the network -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
</dependencies>

2.构建一个RestTemplateConfig

构建RestTemplateConfig为了初始化RestTemplate让它具备验证证书功能。

java 复制代码
/**
 * @Author: LongGE
 * @Date: 2023-08-28
 * @Description:
 */
@Configuration
public class RestTemplateConfig {

    /**
     * 1.创建一个KeyStore,并将需要信任的证书加载到KeyStore中。示例代码如下:
     * @return
     * @throws CertificateException
     * @throws IOException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     */
    @Bean
    public KeyStore createKeyStore() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        FileInputStream inputStream =
                new FileInputStream("D:\\WorkSpace\\local\\online-project\\RequestSpringBoot\\src\\main\\resources\\my-certificate.crt");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(inputStream);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("my-cert", certificate);
        return keyStore;
    }

    /**
     * 2.创建一个TrustManagerFactory,使用上述创建的KeyStore来初始化它
     * @return
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws IOException
     */
    @Bean
    public TrustManagerFactory createTrustManagerFactory() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
        KeyStore keyStore = createKeyStore();
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);
        return trustManagerFactory;
    }

    /**
     * 3.创建一个SSLContext,并使用上述创建的TrustManagerFactory来初始化它。
     * @return
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws KeyStoreException
     * @throws IOException
     * @throws KeyManagementException
     */
    @Bean
    public SSLContext createSSLContext() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, KeyManagementException {
        TrustManagerFactory trustManagerFactory = createTrustManagerFactory();
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
        return sslContext;
    }

    /**
     * 4.创建一个HttpsURLConnectionFactory,使用上述创建的SSLContext来设置HttpsURLConnection的SSLSocketFactory。
     * @return
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     * @throws IOException
     */
    @Bean
    public RestTemplate createRestTemplate() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
        SSLContext sslContext = createSSLContext();
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setSSLContext(sslContext);
        // 创建HttpComponentsClientHttpRequestFactory
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClientBuilder.build());
        // 创建RestTemplate,并设置自定义的SSLSocketFactory
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }

}

二.使用方案

这样构建好的RestTemplate,我们在Controller或者Service就可以通过@Autowried注解引入。

java 复制代码
@RestController
@RequestMapping("/TestController")
public class TestController {

    @Autowired
    private RestTemplate restTemplate;

    private String url = "https://www.houpu.com";

    private String relativePath2 = "/ResponseController/getTestMapping";


    @GetMapping("/test02")
    public String test02() {
        //发起请求
        String fullUrl2 = UriComponentsBuilder.fromHttpUrl(url).path(relativePath2).toUriString();
        String response2 = restTemplate.getForObject(fullUrl2, String.class);
        System.out.println(response2);
        return response2;
    }

}
相关推荐
两个人的幸福online16 小时前
cocos 使用 WebSocket(goEasy版)
网络·websocket·网络协议
@CLoudbays_Martin1119 小时前
什么是IP黑洞?
网络·网络协议·tcp/ip
老蒋新思维21 小时前
创客匠人 2025 万人峰会核心:AI 驱动知识产品变现革新
大数据·人工智能·网络协议·tcp/ip·创始人ip·创客匠人·知识变现
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ21 小时前
aspect实现请求校验,但是WebSocket 端点类不能被 AOP 代理解决方案
网络·websocket·网络协议
老蒋新思维1 天前
创客匠人峰会新视角:AI 时代知识变现的 “组织化转型”—— 从个人 IP 到 “AI+IP” 组织的增长革命
大数据·人工智能·网络协议·tcp/ip·创始人ip·创客匠人·知识变现
Arwen3031 天前
等保2.0三级认证内网IP SM2 SSL证书
网络协议·tcp/ip·ssl
科技块儿1 天前
【方法】IP66.net:如何查到自己的IP?
网络·网络协议·tcp/ip
北京耐用通信1 天前
调试复杂、适配难?耐达讯自动化Ethercat转Devicenet让继电器通讯少走弯路
人工智能·物联网·网络协议·自动化·信息与通信
lx188548698961 天前
HTTPS总结
服务器·网络协议·https
2501_915106321 天前
App HTTPS 抓包实战解析,从代理调试到真实网络流量观察的完整抓包思路
网络协议·http·ios·小程序·https·uni-app·iphone