Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證淺析
需求
最近在負(fù)責(zé)一個(gè)對(duì)接第三方服務(wù)的事情,在對(duì)接期間,因?yàn)榈谌椒?wù)為https的請(qǐng)求,眾所周知,請(qǐng)求https請(qǐng)求會(huì)使用本地的證書公鑰去訪問服務(wù)SSL證書,應(yīng)我本地并沒有對(duì)應(yīng)的SSL證書,所以請(qǐng)求不到服務(wù),請(qǐng)求接口時(shí)報(bào)如下錯(cuò)誤。翻閱資源發(fā)現(xiàn)是可以 忽略SSL認(rèn)證的。
- 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請(qǐng)求的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();
}
}
/**
* 跳過證書效驗(yàn)的sslcontext
*
* @return
* @throws Exception
*/
private static SSLContext createIgnoreVerifySSL() throws Exception {
SSLContext sc = SSLContext.getInstance("TLS");
// 實(shí)現(xiàn)一個(gè)X509TrustManager接口,用于繞過驗(yàn)證,不用修改里面的方法
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();
// 超時(shí)
// factory.setConnectionRequestTimeout(5000);
// factory.setConnectTimeout(5000);
// factory.setReadTimeout(5000);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
// 指定TLS版本
null,
// 指定算法
null,
// 取消域名驗(yàn)證
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 {
//請(qǐng)求地址
String url ="https://.....";
//請(qǐng)求參數(shù)
String requestData = JSON.toJSONString(data);
System.out.println("請(qǐng)求參數(shù):" + requestData);
RestTemplate restTemplate;
if (flag) {
//HTTP繞過SSL證書認(rèn)證
restTemplate = SslUtils.getRestTemplate();
} else {
//普通請(qǐng)求方式
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("開始請(qǐng)求");
//POST返回字節(jié)方式
byte[] response = restTemplate.postForObject(uri, httpEntity, byte[].class);
//GET請(qǐng)求返回字符
//String request = restTemplate.getForObject(uri, String.class);
System.out.println("請(qǐng)求結(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請(qǐng)求忽略ssl證書認(rèn)證的文章就介紹到這了,更多相關(guān)Java https請(qǐng)求忽略ssl證書認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中使用正則表達(dá)式的一個(gè)簡單例子及常用正則分享
這篇文章主要介紹了Java中使用正則表達(dá)式的一個(gè)簡單例子及常用正則分享,本文用一個(gè)驗(yàn)證Email的例子講解JAVA中如何使用正則,并羅列了一些常用的正則表達(dá)式,需要的朋友可以參考下2015-06-06
IntelliJ IDEA創(chuàng)建maven多模塊項(xiàng)目(圖文教程)
這篇文章主要介紹了IntelliJ IDEA創(chuàng)建maven多模塊項(xiàng)目(圖文教程),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09
Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之排序算法
排序算法是《數(shù)據(jù)結(jié)構(gòu)與算法》中最基本的算法之一。排序算法可以分為內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存2022-02-02
java實(shí)現(xiàn)圖的鄰接表存儲(chǔ)結(jié)構(gòu)的兩種方式及實(shí)例應(yīng)用詳解
這篇文章主要介紹了java實(shí)現(xiàn)圖的鄰接表存儲(chǔ)結(jié)構(gòu)的兩種方式及實(shí)例應(yīng)用詳解,鄰接表構(gòu)建圖是必須需要一個(gè)Graph對(duì)象,也就是圖對(duì)象!該對(duì)象包含屬性有:頂點(diǎn)數(shù)、邊數(shù)以及圖的頂點(diǎn)集合,需要的朋友可以參考下2019-06-06
Java數(shù)據(jù)結(jié)構(gòu)之線段樹詳解
線段樹是一種二叉搜索樹,與區(qū)間樹相似,它將一個(gè)區(qū)間劃分成一些單元區(qū)間,每個(gè)單元區(qū)間對(duì)應(yīng)線段樹中的一個(gè)葉結(jié)點(diǎn)。本文將介紹線段樹的Java實(shí)現(xiàn)代碼,需要的可以參考一下2022-01-01

