概述
最近联调的时候需要请求远程webservice,且这个服务是以https开头,在无法协调到证书的情况下只能选择将这个安全验证跳过。
调用异常
- 在没有跳过验证也没有证书的情况,直接访问会报以下异常:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
解决方案
这个异常一般将证书导入即可,但是我们是远程服务无法获取到证书,所以这里只讲如何跳过安全验证。
- 针对POST、get请求采用以下的方法
try
{
//绕过https验证,将这两个放在请求远程服务的最前面
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
catch (Exception e1)
{
e1.printStackTrace();
}
//类的最前面加入静态代码块
static HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
logger.warn("Warning: URL Host: " + urlHostName + " vs. "+ session.getPeerHost());
return true;
}
};
public static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs)
{
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs)
{
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException
{
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) throws java.security.cert.CertificateException
{
return;
}
}
- 针对webservice请求https安全连接
try
{
Service service = new Service();
Call call = null;
call = (Call) service.createCall();
call.setTargetEndpointAddress(new URL(url));
QName qn = new QName(url, method);
call.setOperationName(qn);
// 跳过https证书验证
AxisProperties.setProperty("axis.socketSecureFactory",
"org.apache.axis.components.net.SunFakeTrustSocketFactory");
//应答序列化,不写会报 could not find deserializer for type xxx
QName qn_ret = new QName("urn:BeanService","Result");
call.registerTypeMapping(Result.class, qn_ret, new BeanSerializerFactory(Result.class, qn_ret), new BeanDeserializerFactory(Result.class, qn_ret));
rlt = (Result) call.invoke(new Object[] { inParam });
}
catch (Exception e)
{
//异常打印
}