Java中g(shù)et/post的https請求忽略ssl證書認證淺析
需求
最近在負責(zé)一個對接第三方服務(wù)的事情,在對接期間,因為第三方服務(wù)為https的請求,眾所周知,請求https請求會使用本地的證書公鑰去訪問服務(wù)SSL證書,應(yīng)我本地并沒有對應(yīng)的SSL證書,所以請求不到服務(wù),請求接口時報如下錯誤。翻閱資源發(fā)現(xiàn)是可以 忽略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之前調(diào)用 * * @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”異常 * <p> * 不用導(dǎo)入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"); // 實現(xiàn)一個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; } /** * 構(gòu)造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<Bean> data) throws Exception { try { //請求地址 String url ="https://....."; //請求參數(shù) String requestData = JSON.toJSONString(data); System.out.println("請求參數(shù):" + requestData); RestTemplate restTemplate; if (flag) { //HTTP繞過SSL證書認證 restTemplate = SslUtils.getRestTemplate(); } else { //普通請求方式 restTemplate = new RestTemplate(); } //自定義header傳輸信息(根據(jù)自己的需求設(shè)置) HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8); HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity(JSON.toJSON(data), httpHeaders); URI uri = new URI(url); System.out.println("開始請求"); //POST返回字節(jié)方式 byte[] response = restTemplate.postForObject(uri, httpEntity, byte[].class); //GET請求返回字符 //String request = restTemplate.getForObject(uri, String.class); System.out.println("請求結(jié)束"); if (response == null) { System.out.println("返回值為空"); } String result = new String(response, "utf-8"); System.out.println("返回結(jié)果:" + result); } catch (Exception e) { e.printStackTrace(); } }
總結(jié)
到此這篇關(guān)于Java中g(shù)et/post的https請求忽略ssl證書認證的文章就介紹到這了,更多相關(guān)Java https請求忽略ssl證書認證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java怎么設(shè)置代理ip實現(xiàn)高效網(wǎng)絡(luò)請求
無論是在爬蟲、API調(diào)用還是網(wǎng)絡(luò)測試中,代理IP的使用都變得愈發(fā)重要,本文我們主要來介紹一下如何在Java中設(shè)置代理IP實現(xiàn)高效網(wǎng)絡(luò)請求吧2024-11-11JAVA讀取HDFS的文件數(shù)據(jù)出現(xiàn)亂碼的解決方案
這篇文章主要介紹了JAVA讀取HDFS的文件數(shù)據(jù)出現(xiàn)亂碼的解決方案,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-11-11