笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

https

Posted on 2025-04-09 10:14  草妖  阅读(10)  评论(0)    收藏  举报

背景:服务器A为https的配置环境,服务器B为未配置https的环境,自己的项目部署到服务器B,并且访问服务器A的https接口将出现以下错误:

Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

方法一:配置spring boot以信任所有的证书(注:不推荐生产环境)

pom.xml

<!-- https处理 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.14</version>
        </dependency>

对于RestTemplate:

HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build();
        clientHttpRequestFactory.setHttpClient(HttpClients.custom().setSSLContext(sslContext).build());
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        if (!targetUrl.endsWith("/")) {
            targetUrl += "/";
        }
        targetUrl += targetBody + "?" + getParams;
        HttpEntity<String> formEntity = new HttpEntity<>(null, httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(targetUrl, HttpMethod.GET, formEntity, String.class);
        if (response.getStatusCode() == HttpStatus.OK) {
            return response.getBody();
        }
        return null;

对于WebClient:(未验证)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.transport.logging.AdvancedByteBufFormat;
import reactor.netty.http.client.HttpClient;
import java.security.cert.*;
import javax.net.ssl.*;
 
@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient() {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        }};
        SSLContext sslContext = SSLContextBuilderCustomizer(trustAllCerts).build();
        HttpClient httpClient = HttpClient.create().secure(sslSpec -> sslSpec.sslContext(sslContext));
        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();
    }
}

 

对于java.net.URL:

package ****.****.base;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class TrustAllCerts implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {
        // 接受所有客户端证书
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) {
        // 接受所有服务器证书
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }
}


package ***.***.base;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class CustomSSLSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory delegate;

    public CustomSSLSocketFactory() throws Exception {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[]{new TrustAllCerts()}, new java.security.SecureRandom());
        delegate = sslContext.getSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return delegate.createSocket(s, host, port, autoClose);
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return delegate.createSocket(host, port);
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return delegate.createSocket(host, port, localHost, localPort);
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return delegate.createSocket(host, port);
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return delegate.createSocket(address, port, localAddress, localPort);
    }
}


/**
     * 检测网络资源是否存在/图片是否存在
     * */
    public boolean checkResourceExists(String webFilePath) {
        try {
            /*
            URL url = new URL(webFilePath);
            URLConnection uc = url.openConnection();
            InputStream in = uc.getInputStream();
            if (webFilePath.equalsIgnoreCase(uc.getURL().toString())) {
                in.close();
            }
            return true;
            */
            URL url = new URL(webFilePath);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setSSLSocketFactory(new CustomSSLSocketFactory()); // 设置自定义的SSL套接字工厂
            connection.setRequestMethod("GET"); // 或其他HTTP方法,例如POST等。 具体取决于你的需求。
            // 设置其他需要的请求属性,如请求头等。 例如:connection.setRequestProperty("key", "value");
            if (connection.getResponseCode()==200) {
                // 正常流
                InputStream responseStream =connection.getInputStream();
            }else{
                // 错误流
                InputStream responseStream =connection.getErrorStream();
            }
            connection.disconnect();
            return true;
        } catch (Exception e) {
            return false;
        }
    }