基于HttpClient接口开发实例(四)

前言


本节我们将学习一下关于HttpClient请求在遇到SSL证书认证时如何绕过认证环节。如今在整个Internet中主流的Protocol HTTPS 以它自身的有时几乎替代了HTTP,基于HTTPS自由的特性,它需要证书认证来保证请求URL和数据的安全可靠,因而本节将重点学习一下如何在使用HTTPS请求数据是绕开SSL认证证书。在整个实现的过程中我们将选择性讲解一下代码试下你的逻辑。

  • HttpClientUtils.java

    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;
    import java.io.OutputStreamWriter;  
    import java.net.URL;  
    import java.net.URLConnection;  
    import org.apache.commons.io.IOUtils;
    
    /**
     * 封装新的HttpClient 请求,绕过签证
     * @author baixiaodong
     *
     */
    public class HttpClientUtils {
    
        /**
         * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
         * 
         * @throws Exception
         */
        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 {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
    
            public boolean isServerTrusted(X509Certificate[] certs) {
                return true;
            }
    
            public boolean isClientTrusted(X509Certificate[] certs) {
                return true;
            }
    
            public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
                return;
            }
    
            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() {
                public boolean verify(String urlHostName, SSLSession session) {
                    System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                    return true;
                }
            };
            trustAllHttpsCertificates();
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
        }
    
        /**
         * 忽略SSL证书的Get请求
         * @param url
         * @param timeOut 默认 3000
         * @return
         * @throws Exception
         */
        public static String getRequest(String url, int timeOut) throws Exception {
            URL u = new URL(url);
            if ("https".equalsIgnoreCase(u.getProtocol())) {
                ignoreSsl();
            }
            URLConnection conn = u.openConnection();
            conn.setConnectTimeout(timeOut);
            conn.setReadTimeout(timeOut);
            return IOUtils.toString(conn.getInputStream());
        }
    
        /**
         * 忽略SSL证书的POST请求
         * @param urlAddress
         * @param args
         * @param timeOut
         * @return
         * @throws Exception
         */
        public static String postRequest(String urlAddress, String args, int timeOut) throws Exception {
            URL url = new URL(urlAddress);
            if ("https".equalsIgnoreCase(url.getProtocol())) {
                ignoreSsl();
            }
            URLConnection u = url.openConnection();
            u.setDoInput(true);
            u.setDoOutput(true);
            u.setConnectTimeout(timeOut);
            u.setReadTimeout(timeOut);
            OutputStreamWriter osw = new OutputStreamWriter(u.getOutputStream(), "UTF-8");
            osw.write(args);
            osw.flush();
            osw.close();
            u.getOutputStream();
            return IOUtils.toString(u.getInputStream());
        }
    }
    

小结

使用如上方法便可以绕过证书认证部分,当实际上我是不推荐这样做的,因为这种获取数据的行为属于Cheat行为,理论上是违背互联网安全协议的,其次我们没有通过SSL证书认证授权,无法确保URL和数据的正确性和可用性。

猜你喜欢

转载自blog.csdn.net/u012437781/article/details/80019760