java訪問非經過信任證書https的方法
阿新 • • 發佈:2019-01-27
由於專案需要,需要呼叫第三方的API介面,為了簡單方便與快速開發,便採用了httpClient來進行呼叫。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
但在第三方的一個HTTPS的介面時,IDE中報瞭如下錯誤。
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
解決辦法:
將httpClient中關於證書認證的實現機制註釋掉,即不對任何https的證書進行校驗。程式碼如下:
import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; 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.apache.http.impl.conn.PoolingHttpClientConnectionManager; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; /** * 信任https證書 * * @author puhaiyang * @date 2018/11/14 */ public class SslUtil { public static CloseableHttpClient SslHttpClientBuild() { Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", trustAllHttpsCertificates()) .build(); //建立ConnectionManager,新增Connection配置資訊 PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build(); return httpClient; } /** * 信任所有證書 */ private static SSLConnectionSocketFactory trustAllHttpsCertificates() { SSLConnectionSocketFactory socketFactory = null; TrustManager[] trustAllCerts = new TrustManager[1]; TrustManager tm = new miTM(); trustAllCerts[0] = tm; SSLContext sc = null; try { sc = SSLContext.getInstance("TLS");//sc = SSLContext.getInstance("TLS") sc.init(null, trustAllCerts, null); socketFactory = new SSLConnectionSocketFactory(sc, NoopHostnameVerifier.INSTANCE); //HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return socketFactory; } static class miTM implements TrustManager, X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(X509Certificate[] certs, String authType) { //don't check } public void checkClientTrusted(X509Certificate[] certs, String authType) { //don't check } } }
然後將以前的httpClient生成的程式碼用上寫剛剛寫的這個來進行生成就可以了!
// 建立httpClient物件
// CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = SslUtil.SslHttpClientBuild();