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 ...
随机推荐
- rh358 002 fact变量获取 ansible配置网络 service_facts
通过ansible 获取网络信息 1.如何获取fact事实变量 方式1: ansible servera -m servera 方式2: 剧本 [root@workstation ansible]# ...
- Android Kotlin Annotation Processer
Annotation Processer 注解处理器(Annotation Processer)是javac内置的注解处理工具,可以在编译时处理注解,让我们自己做相应的处理.比如生成重复度很高的代码, ...
- C语言:多功能计算器
好家伙,这个东西有点折磨 这是一个多功能计算器 #include<stdio.h> #include<math.h> #include<windows.h> voi ...
- .md图片链接转存并替换路径,及相关报错解决方法
最初我想把Typora中.md文件中的web图片链接都下载保存到本地,并且替换.md文本中的路径 说干就干,因为在网上没有找到现成的程序所以自己写了这个程序 思路是循环查找文件夹中的文件,然后yiel ...
- for--else大坑问题
这是一次偶然发现的问题,做一下记录 a = [{'w0', 'b0', 'v0'}, {'w1', 'b1', 'v1'}, {'w2', 'b2', 'v2'}] for i in a: for j ...
- v-if和v-for的优先级是什么?
一.作用 v-if 指令用于条件性地渲染一块内容.这块内容只会在指令的表达式返回 true值的时候被渲染 v-for 指令基于一个数组来渲染一个列表.v-for 指令需要使用 item in item ...
- KingbaseES R6 集群修改物理IP和VIP案例
在用户的实际环境里,可能有时需要修改主机的IP,这就涉及到集群的配置修改.以下以例子的方式,介绍下KingbaseES R6集群如何修改IP. 一.案例测试环境 操作系统: [KINGBASE@nod ...
- x-pack设置完毕后,es-head无法登陆的问题, 登录需要账号密码的问题
在elasticsearch.yml中添加如下三行配置 http.cors.enabled: true http.cors.allow-origin: "*" http.cors. ...
- Elasticsearch:inverted index,doc_values及source
以后会用到的相关知识:索引中某些字段禁止搜索,排序等操作 当我们学习Elasticsearch时,经常会遇到如下的几个概念: Reverted index doc_values source? 这个几 ...
- filebeat知识点
在Filebeat的根目录下,有一个叫做filebeat.yml的文件. filebeat.inputs: - type: log enabled: true paths: - ./sample.lo ...