使用RestTemplate时出现“找不到与<api.hostname.net>匹配的主题替代DNS名称”错误

时间:2018-07-13 09:14:38

标签: java spring apache spring-boot ssl

我一直在尝试将RestTemplate请求发送到如下所示的API网址:

https://api.something.hostname.net/api/key=key&parameter1=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提供程序的证书问题?

0 个答案:

没有答案