Https Webservice接口的免证书调用
前言
在调用https协议的Webservice接口时,如果没有做证书验证,一般会报javax.net.ssl.SSLHandshakeException错误,如果是Was中间件,更会产生jar依赖问题。
一般的解决方案是利用jdk的keytool(ikeyman)生成公钥并导入进jre的信任公钥库中。这种方法略显繁琐复杂。
本文以Axis、httpclient(其他客户端同理)调用方式为例,说明在不导入证书的情况下如何绕过验证调用Https协议的Webservice接口,适用于Sun/Oracle JDK和IBM JDK(was中间件)。
思路
client发起https调用时,会使用默认的SocketFactory,对服务端证书进行验证,由于没有正确的公钥验签,是无法握手成功的。因此,对于自签名的服务端,我们需要重写一个SocketFactory,跳过证书验证,并用这个SocketFactory替换client本身默认的SocketFactory。这种方案不仅适用于Webservice框架的客户端,亦常用于Httpclient发起的https调用。
方案
Axis调用
在调用Webservice接口时,替换axis.socketSecureFactory。
使用Sun/Oracle JDK的情况下可以直接用如下替换:
AxisProperties.setProperty("axis.socketSecureFactory","org.apache.axis.components.net.SunFakeTrustSocketFactory");
也可以写一个自定义的SocketFactory类进行替换(同时适用于IBM JDK):继承Axis的父类JSSESocketFactory ,并且重写父类initFactory方法
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Hashtable;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.axis.components.net.JSSESocketFactory;
/**
* 跳过HTTPS验证
* @since 2022-06-09
*/
public class MyTLSSocketSecureFactory extends JSSESocketFactory {
public MyTLSSocketSecureFactory(Hashtable attributes) {
super(attributes);
// TODO Auto-generated constructor stub
}
// Create a trust manager that does not validate certificate chains
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
TrustManager[] trustAllCerts = new TrustManager[] { trustManager };
@Override
public void initFactory() throws IOException {
SSLContext ctx;
try {
ctx = SSLContext.getInstance("TLSv1.2");
// ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null, trustAllCerts, null);
// ctx.init(null, trustAllCerts, new java.security.SecureRandom());
sslFactory = ctx.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在调用前设置:
// 在客户端的ServiceSoapBindingStub.createCall()中设置
AxisProperties.setProperty("axis.socketSecureFactory", MyTLSSocketSecureFactory.class.getName());
Webservice接口调用:
try {
URL endpoint = new URL("https://host:port/WebService?wsdl");
webservice = new WebServiceLocator().getWebServicePort(endpoint);
} catch (Exception e) {
e.printStackTrace();
}
HttpClient调用
可以使用Httpclient作为Webservice客户端发起免征书调用,优点是兼容性更强,缺点是需要自定义封装和解析soap xml报文。
Httpclient依赖jar:httpcore-4.4.4.jar,httpclient-4.5.jar(在was中间件下需要设置共享库,否则会发生jar冲突)。
- 获取调用报文
可以通过soapUI调试Webservice接口,获取调用时发送的soap xml格式。
- 创建绕过SSL验证的Httpclient客户端
/**
* 在调用SSL之前需要重写验证方法,取消检测SSL
* 创建ConnectionManager,添加Connection配置信息
* @return HttpClient 支持https
*/
private static HttpClient getHttpClient() {
try {
// 在调用SSL之前需要重写验证方法,取消检测SSL
X509TrustManager trustManager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
ctx.init(null, new TrustManager[] { trustManager }, null);
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
// 创建Registry
RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(Boolean.TRUE)
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout).build();
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", socketFactory).build();
// 创建ConnectionManager,添加Connection配置信息
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig).build();
return closeableHttpClient;
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
- 发起Webservice接口调用
public static String doPost(String url, String soapXml, String soapAction) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
String result = "";
// 创建httpClient实例
httpClient = (CloseableHttpClient) getHttpClient();
// 创建httpPost远程连接实例
HttpPost httpPost = new HttpPost(url);
// 设置请求头
httpPost.addHeader("Content-Type", "text/xml;charset=UTF-8");
httpPost.setHeader("SOAPAction", SOAPAction);
httpPost.setEntity(new StringEntity(soapXml, "UTF-8"));
try {
// httpClient对象执行post请求,并返回响应参数对象
httpResponse = httpClient.execute(httpPost);
// 从响应对象中获取响应内容
HttpEntity entity = httpResponse.getEntity();
result = EntityUtils.toString(entity);
} catch (ClientProtocolException e) {
e.printStackTrace();
Logger.error("发送POST请求异常:" + e.getMessage(), e);
} catch (IOException e) {
e.printStackTrace();
Logger.error("发送POST请求异常:" + e.getMessage(), e);
} finally {
// 关闭资源
if (null != httpResponse) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
- 解析返回的result XML。此处不做详解。
参考链接
HttpClient调用WebService接口_小豆的编程世界...的博客
httpclient作为客户端调用webservice_aperise的博客
Https Webservice接口的免证书调用的更多相关文章
- java获取https网站证书,附带调用https:webservice接口
一.java 获取https网站证书: 1.创建一个java工程,新建InstallCert类,将以下代码复制进去 package com; import java.io.BufferedReader ...
- webservice接口的开发和调用
一.WebService的开发手段 使用Java开发WebService时可以使用以下两种开发手段 1. 使用JDK开发(1.6及以上版本) 2.使用CXF框架开发(工作中) 二.使用JDK开发Web ...
- 使用HttpClient携带pfx证书调用HTTPS协议的WebService
调用第三方服务时,厂商提供了一个WSDL文件.调用的地址和一个后缀为pfx的证书文件,通过SOUPUI记载证书是可以正常调用WebService服务,那么如何将该服务转换为代码呢? 咨询了厂商的支持, ...
- 调用 Https WebService 使用程序自动生成代理类
1 商家提供的WebService接口: https://ws.nciic.org.cn/nciic_ws/services/NciicServices?wsdl 2 在浏览器里打开这个地址,会显示 ...
- [置顶]
Java WebService接口生成和调用 图文详解
webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...
- Java WebService接口生成和调用 图文详解>【转】【待调整】
webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...
- 如何调用别人提供的webservice接口
当我们拿到一个接口的时候,先别急着去调用它,我们得先测试这个接口是否正确,是否能调用成功,以及返回的数据是否是我们需要的类型等等.这时候我们需要一个工具,比如SoapUI.(最好用绿色免安装版的.)然 ...
- python使用suds调用webservice接口
最近做接口对接,遇到了.net开发的webservice接口,因为python第一次与webservice对接,连问带查,最后使用suds库来实现了 1.安装suds mac: sudo pip in ...
- java实现https免证书认证
java实现https免证书认证 解决方法: 1.下载两个包,httpclient-4.2.jar和httpcore-4.2.jar,复制以下代码就可使用. 2.调用类代码: String htt ...
随机推荐
- Hnoi2014世界树
题面 说明/提示 N<=300000, q<=300000,m[1]+m[2]+...+m[q]<=300000 题解 这道题一看 "m[1]+m[2]+...+m[q]& ...
- qt C2144 语法错误,需要在类型前添加;(分号)
可能原因:有部分头文件未以";"结尾.
- 移动教室APP
软件名:VERIMAG 官网链接:http://www.verimag.ru/mobilnoe-obrazovanie.html 移动课堂,充满活力的气息.走在时代前沿的同时,也对教育者对于编制课件的 ...
- openstack中Cinder组件简解
一,Cinder组件介绍 概念 cinder组件作用: 块存储服务,为运行实例提供稳定的数据块存储服务 块存储服务,提供对 volume 从创建到删除整个生命周期的管理 二,常用操作 1.Volume ...
- yum install lrzsz
yum install lrzsz rz:从本地上传文件至服务器 sz filename:从服务器下载文件至本地
- 引擎之旅 前传:C++代码规范
自己以前写代码时,一个项目一个风格.单人开发的工作使得我并没有注意到代码规范性和可读性的问题.每当项目结束后,看到自己杂乱无章的代码,完全没有二次开发和重构的欲望. 写代码就应该像写诗一样优雅. by ...
- OpenDataV低代码平台新增组件流程
OpenDataV计划采用子库的方式添加子组件,即每一个组件都当做一个子库,子库有自己的依赖,而项目本身的依赖只针对框架,因此每一个组件我们都当做一个子库来开发.下面我带着大家一步步详细的开发一个数字 ...
- Python图像处理丨带你认识图像量化处理及局部马赛克特效
摘要:本文主要讲述如何进行图像量化处理和采样处理及局部马赛克特效. 本文分享自华为云社区<[Python图像处理] 二十.图像量化处理和采样处理及局部马赛克特效>,作者: eastmoun ...
- JS 模块化 - 03 AMD 规范与 Require JS
1 AMD 规范介绍 AMD 规范,全称 Asynchronous Module Definition,异步模块定义,模块之间的依赖可以被异步加载. AMD 规范由 Common JS 规范演进而来, ...
- frp内网穿透实战
什么是frp frp是一个使用非常简单的开源内网穿透软件,代码地址:https://github.com/fatedier/frp ,使用条前提你需要有一台公网服务器,大致原理是:公网服务器监听某个端 ...