生产中遇到了一个问题:由于第三方服务商更新服务器证书,导致向其推送数据出现SSL证书认证失败。网上搜了一堆,都无法生效,最终找到了一个完美解决方案:
在代码层跳出SSL验证!
1、观察异常日志信息如下:
2、新增跳过证书的类,TrustAllTrustManager.java代码如下
public class TrustAllTrustManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
3、在自己的发送controller中添加如下代码
// 直接通过主机认证
HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
// 配置认证管理器
javax.net.ssl.TrustManager[] trustAllCerts = {new TrustAllTrustManager()};
SSLContext sc = SSLContext.getInstance("SSL");
SSLSessionContext sslsc = sc.getServerSessionContext();
sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 激活主机认证
HttpsURLConnection.setDefaultHostnameVerifier(hv);
URL url = new URL(url);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
4:比如我的调用第三方接口类如下:
//XXX接口(出库备料)
@RequestMapping("/PostMidStoreOut")
@ResponseBody
public Map<String, Object> PostMidStoreOut(String sb){
Map<String, Object> map = new HashMap<String, Object>();
try {
// 直接通过主机认证
HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
TrustManager[] trustAllCerts = {new TrustAllTrustManager()};
SSLContext sc = SSLContext.getInstance("SSL");
SSLSessionContext sslsc = sc.getServerSessionContext();
sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 地址
URL url = new URL(config.getWms()+"/XXXX/XXXX");
// 调用的方法
String soapActionString = "PostMidStoreOut";
// 激活主机认证
HttpsURLConnection.setDefaultHostnameVerifier(hv);
// 打开链接
HttpURLConnection con = (HttpURLConnection) url.openConnection();
String xmlStr = sb.toString();
con.setRequestMethod("POST");
con.setRequestProperty("content-type", "text/xml; charset=utf-8");
con.setRequestProperty("Content-Length", String.valueOf(xmlStr.getBytes().length));
con.setRequestProperty("soapActionString", soapActionString);
// post请求需要设置
con.setDoOutput(true);
con.setDoInput(true);
// 对请求body 往里写xml 设置请求参数
OutputStream ops = con.getOutputStream();
ops.write(xmlStr.getBytes());
ops.flush();
ops.close();
// 设置响应回来的信息
if (con.getResponseCode() == 200) {
InputStream ips = con.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int length = 0;
while ((length = ips.read(buf)) != -1) {
baos.write(buf, 0, length);
baos.flush();
}
byte[] responsData = baos.toByteArray();
baos.close();
// 处理写响应信息
String responsMess = new String(responsData, "utf-8");
map.put("result", true);
map.put("status", 0);
map.put("responsMess", responsMess);
} else {
map.put("status", 1);
map.put("result", false);
map.put("Msg", "传输数据错误");
map.put("ResponseMessage", con.getResponseMessage());
}
} catch (Exception e) {
e.printStackTrace();
map.put("status", 1);
map.put("Msg", "传输数据错误");
map.put("result", false);
}
return map;
}