JAVA跳过SSL证书检查进行接口请求

遇到这么一个需求,我们是两套系统内网部署,A系统签了本地的ssl证书,B系统需要访问A系统的一个接口,在测试环境时,没有使用ssl,进行接口开发,没有问题,后面生产环境后,接口不通,报错“

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is 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"

这个“PKIX path building failed”,大概就是提示无法获取有效的证书,因此JAVA进行常规的POST请求时,没法实现该功能,常规的POST请求如下:

/**
     * 发送POST请求
     * @param url
     * @param params
     * @return
     */
    public String sendPOSTRequest(String url, MultiValueMap<String, Object> params) {
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        // 执行HTTP请求,将返回的结构使用String类格式化
        ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }

需要将请求修改为一下方式:需要实现证书信任管理器,MyX509TrustManager.java 和NullHostNameVerifier.java

MyX509TrustManager.java源码如下:

package com.dhproject.utils.ssl;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
 * 证书信任管理器(用于https请求)
 *
 */
public class MyX509TrustManager implements X509TrustManager {
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

NullHostNameVerifier.java源码如下:

package com.dhproject.utils.ssl;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
public class NullHostNameVerifier implements HostnameVerifier{
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
}

通过证书信任管理器实现POST请求如下:

package com.dhproject.utils.ssl;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;

public class SslPost {
    /**
     * 发送POST请求
     * @param urlStr
     * @param param
     * @return
     */
    public static String sendPOSTRequest(String urlStr,String param) {
        try{
            //设置可通过ip地址访问https请求
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(urlStr);
            HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
            con.setSSLSocketFactory(ssf);
            con.setRequestMethod("POST"); // 设置以POST方式提交数据
            con.setDoInput(true); // 打开输入流,以便从服务器获取数据
            con.setDoOutput(true);// 打开输出流,以便向服务器提交数据
            //设置发送参数
            PrintWriter out = new PrintWriter(new OutputStreamWriter(con.getOutputStream(),"UTF-8"));
            out.print(param);
            out.flush();
            out.close();
            //读取请求返回值
            InputStreamReader in = new InputStreamReader(con.getInputStream(),"UTF-8");
            BufferedReader bfreader = new BufferedReader(in);
            String result = "";
            String line = "";
            while ((line = bfreader.readLine()) != null) {
                result += line;
            }
            return result;
        }catch (Exception e){
            return  "";
        }
    }
}

调用代码如下:

/**
     * 查询
     * @param roomId
     * @param orderByColumn
     * @param isAsc
     * @return
     */
    @PostMapping("/list")
    @ResponseBody
    public Object list(Long roomId,String orderByColumn,String isAsc)
    {
        return SslPost.sendPOSTRequest("https://localhost/api/api","roomId="+(roomId==null?"":roomId.toString())+"&orderByColumn="+orderByColumn+"&isAsc="+isAsc);
    }

猜你喜欢

转载自blog.csdn.net/zlxls/article/details/128939145
今日推荐