如何在 spring webclient 中禁用主机名验证?

我正在使用 spring webflux webclient 工具来调用 API。API服务器地址为HTTPS,是不带域名的IP地址。我需要在 webclient 中禁用主机名验证。现在异常如下


Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 180.101.147.89 found

    at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:168) ~[na:1.8.0_211]

    at sun.security.util.HostnameChecker.match(HostnameChecker.java:94) ~[na:1.8.0_211]

    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:461) ~[na:1.8.0_211]

    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:442) ~[na:1.8.0_211]

    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:260) ~[na:1.8.0_211]

    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144) ~[na:1.8.0_211]

    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1626) ~[na:1.8.0_211]

    ... 28 common frames omitted

@Bean

    public WebClient telcomWebclient(WebClient.Builder webClientBuilder,

                                     @Value("${telcom.api.host}") String telcomApiHost,

                                     @Value("${telcom.api.certificate-name}") String telcomApiCertificateName,

                                     @Value("${telcom.api.certificate-store-pass}") String telcomApiCertificateStorePass) {

        try {

            KeyStore selfCert = KeyStore.getInstance("pkcs12");

            selfCert.load(getClass().getResourceAsStream("/cert/outgoing.CertwithKey.pkcs12"), "IoM@1234".toCharArray());

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");

            kmf.init(selfCert, "IoM@1234".toCharArray());


            KeyStore caCert = KeyStore.getInstance("jks");

            caCert.load(getClass().getResourceAsStream("/cert/" + telcomApiCertificateName), telcomApiCertificateStorePass.toCharArray());

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");

            tmf.init(caCert);



呼啦一阵风
浏览 244回答 1
1回答

慕盖茨4494581

实际上 SNIMatcher 仅适用于服务器端。这可以通过在 matches() 方法的返回上放置一个断点来验证。执行永远不会在该断点处停止。跳过主机名验证的实际原因是,当覆盖 SSLParameters 时,新的 params.identificationAlgorithm 值为 null 而不是“HTTPS”。这是一个更简单的代码,它和上面的一样有效。           HttpClient.create().secure(sslContextSpec -> sslContextSpec                   .sslContext(sslContext)                   .handlerConfigurator(sslHandler -> {                       SSLEngine engine = handler.engine();                       SSLParameters params = new SSLParameters(engine.getSSLParameters().getCipherSuites(), engine.getSSLParameters().getProtocols());                       // With java update null value is no longer sufficient to skip host name verification                       params.setEndpointIdentificationAlgorithm("");                       engine.setSSLParameters(params);                   }));
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java