SpringBoot RestTemplate使用自签名ssl证书,信任自定义的服务器ca证书

本文在SpringBoot RestTemplate的基础上,介绍如何设置自定义的https客户端证书和把信任的服务器ca证书加到spring框架的证书信任管理器中。最近的工作中,遇到第三方服务的https不使用ca机构提供的证书,而是使用自定义的证书,同时客户端也要提供证书给服务器验证,如果只是简单地使用RestTemplate访问这些第三方服务,会有400 HTTPStatus错误。

目录

  • 普通的restTemplate
  • 自定义sslConfig的restTemplate
  • restTemplate的使用
  • 具体代码请参考GitHub项目

普通的restTemplate

@Bean("restTemplate20s")
RestTemplate restTemplate20s() {
	SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
	// 连接超时时间
	requestFactory.setConnectTimeout(2000);
	// 读取超时时间
	requestFactory.setReadTimeout(20000);
	RestTemplate restTemplate = new RestTemplate(requestFactory);

	// 解决中文乱码问题
	restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

	return restTemplate;
}

自定义sslConfig的restTemplate

    @Bean("restTemplate")
    RestTemplate restTemplate() throws Exception {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setConnectionRequestTimeout(5000);
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(5000);

        CloseableHttpClient httpClient = initSSLConfig();
        factory.setHttpClient(httpClient);

        RestTemplate restTemplate = new RestTemplate(factory);

        // 解决中文乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

        return restTemplate;
    }

    // 客户证书验证密码,请根据outgoing.CertwithKey.pkcs12文件修改
    private static String SELFCERTPWD = "12345";
    // 信任客户端验证密码,请根据ca.jks文件修改
    private static String TRUSTCAPWD = "54321";

    public CloseableHttpClient initSSLConfig() throws Exception {

        // 1 设置客户端证书
        KeyStore selfCert = KeyStore.getInstance("pkcs12");
        selfCert.load(RestConfiguration.class.getClassLoader().getResourceAsStream("cert/outgoing.CertwithKey.pkcs12"),
                SELFCERTPWD.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
        kmf.init(selfCert, SELFCERTPWD.toCharArray());

        // 2 向信任管理器中导入服务器的ca认证证书
        KeyStore caCert = KeyStore.getInstance("jks");
        caCert.load(RestConfiguration.class.getClassLoader().getResourceAsStream("cert/ca.jks"), TRUSTCAPWD.toCharArray());
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
        tmf.init(caCert);

        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        // 3 设置不认证域名 (设置DefaultHostnameVerifier.verify直接返回false)
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sc, new DefaultHostnameVerifier());

        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                .build();

        return httpClient;

    }

restTemplate的使用

@Service
public class TestService {

    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;

    public Object post() {
        String url = "https://31.23.1.0:9080/command";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("deviceId", "21312112");
        jsonObject.put("expireTime", 0);
        jsonObject.put("maxRetransmit", 1);
        jsonObject.put("callbackUrl", "https://www.baidu.com");
        HttpEntity<JSONObject> r = new HttpEntity<>(jsonObject, getHeaders());
        JSONObject rep = restTemplate.postForObject(url, r, JSONObject.class);
        return rep;
    }

    public HttpHeaders getHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("Authorization", "Bearer tokenString");
        return headers;
    }

}

具体代码请参考GitHub项目

GitHub

你可能感兴趣的:(SpringBoot)