我一直在尝试将RestTemplate请求发送到如下所示的API网址:
https://api.something.hostname.net/api/key=key¶meter1=val1&etc
应该返回JSON响应。但这会产生以下错误:
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <api.something.hostname.net> doesn't match any of the subject alternative names: [sni-required.hostname.com]
然后,我将按照以下方式实现自己的RestTemplate(来自link):
public RestTemplate getRestTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException, CertificateException {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(createAcceptSelfSignedCertificateClient());
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
private static CloseableHttpClient createAcceptSelfSignedCertificateClient()
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
// use the TrustSelfSignedStrategy to allow Self Signed Certificates
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
// we can optionally disable hostname verification.
// if you don't want to further weaken the security, you don't have to include this.
HostnameVerifier allowAllHosts = new NoopHostnameVerifier();
// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy
// and allow all hosts verifier.
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);
// finally create the HttpClient using HttpClient factory methods and assign the ssl socket factory
return HttpClients
.custom()
.setSSLSocketFactory(connectionFactory)
.build();
}
现在它抛出:
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching api.rasp.yandex.net found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:214) ~[na:1.8.0_172]
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96) ~[na:1.8.0_172]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) ~[na:1.8.0_172]
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436) ~[na:1.8.0_172]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:200) ~[na:1.8.0_172]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[na:1.8.0_172]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596) ~[na:1.8.0_172]
... 56 common frames omitted
link示例使用HttpClient发出成功请求。我可以解决RestTemplate的问题还是必须转到HttpClient?
在开发阶段如何暂时禁用SSL检查?这是可以在本地解决的问题,还是API提供程序的证书问题?