Java get/post的https请求忽略ssl证书认证

需求

最近在负责一个对接第三方服务的事情,在对接期间,因为第三方服务为https的请求,众所周知,请求https请求会使用本地的证书公钥去访问服务SSL证书,应我本地并没有对应的SSL证书,所以请求不到服务,请求接口时报如下错误。翻阅资源发现是可以 忽略SSL认证的。
  • unable to find valid certification path to requested target

工具类

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SslUtils {
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    static class miTM implements TrustManager, X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
            return;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
            return;
        }
    }

    /**
     * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
     *
     * @throws Exception
     */
    public static void ignoreSsl() throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            @Override
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

    /**
     * 避免HttpClient的”SSLPeerUnverifiedException: peer not authenticated”异常
     * 

* 不用导入SSL证书 * * @param base * @return */ public static HttpClient wrapClient(HttpClient base) { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} }; ctx.init(null, new TrustManager[]{tm}, null); SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(ssf).build(); return httpclient; } catch (Exception ex) { ex.printStackTrace(); return HttpClients.createDefault(); } } /** * 跳过证书效验的sslcontext * * @return * @throws Exception */ private static SSLContext createIgnoreVerifySSL() throws Exception { SSLContext sc = SSLContext.getInstance("TLS"); // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法 X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[] { trustManager }, null); return sc; } /** * 构造RestTemplate * * @return * @throws Exception */ public static RestTemplate getRestTemplate() throws Exception { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); // 超时// factory.setConnectionRequestTimeout(5000);// factory.setConnectTimeout(5000);// factory.setReadTimeout(5000); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(), // 指定TLS版本 null, // 指定算法 null, // 取消域名验证 new HostnameVerifier() { @Override public boolean verify(String string, SSLSession ssls) { return true; } }); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); factory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(factory); // 解决中文乱码问题 restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); return restTemplate; }}

使用方法

 @Override
    public void completionIndexPushToODS(List data) throws Exception {
        try {
        	//请求地址
            String url ="https://.....";
            //请求参数
            String requestData = JSON.toJSONString(data);
            System.out.println("请求参数:" + requestData);

            RestTemplate restTemplate;
            if (flag) {
            	//HTTP绕过SSL证书认证
                restTemplate = SslUtils.getRestTemplate();
            } else {
            	//普通请求方式
                restTemplate = new RestTemplate();
            }
            //自定义header传输信息(根据自己的需求设置)
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            
            HttpEntity<MultiValueMap> httpEntity = new HttpEntity(JSON.toJSON(data), httpHeaders);
            URI uri = new URI(url);
            System.out.println("开始请求");
            //POST返回字节方式
            byte[] response = restTemplate.postForObject(uri, httpEntity, byte[].class);
           	//GET请求返回字符
            //String request = restTemplate.getForObject(uri, String.class);

            System.out.println("请求结束");
            if (response == null) {
                System.out.println("返回值为空");
            }
            String result = new String(response, "utf-8");
            System.out.println("返回结果:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/f250400e37.html