前言

在调用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冲突)

  1. 获取调用报文

可以通过soapUI调试Webservice接口,获取调用时发送的soap xml格式。

  1. 创建绕过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);
}
}
  1. 发起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;
}
  1. 解析返回的result XML。此处不做详解。

参考链接

HttpClient调用WebService接口_小豆的编程世界...的博客

httpclient作为客户端调用webservice_aperise的博客

Https Webservice接口的免证书调用的更多相关文章

  1. java获取https网站证书,附带调用https:webservice接口

    一.java 获取https网站证书: 1.创建一个java工程,新建InstallCert类,将以下代码复制进去 package com; import java.io.BufferedReader ...

  2. webservice接口的开发和调用

    一.WebService的开发手段 使用Java开发WebService时可以使用以下两种开发手段 1. 使用JDK开发(1.6及以上版本) 2.使用CXF框架开发(工作中) 二.使用JDK开发Web ...

  3. 使用HttpClient携带pfx证书调用HTTPS协议的WebService

    调用第三方服务时,厂商提供了一个WSDL文件.调用的地址和一个后缀为pfx的证书文件,通过SOUPUI记载证书是可以正常调用WebService服务,那么如何将该服务转换为代码呢? 咨询了厂商的支持, ...

  4. 调用 Https WebService 使用程序自动生成代理类

    1 商家提供的WebService接口:  https://ws.nciic.org.cn/nciic_ws/services/NciicServices?wsdl 2 在浏览器里打开这个地址,会显示 ...

  5. [置顶] Java WebService接口生成和调用 图文详解

    webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...

  6. Java WebService接口生成和调用 图文详解>【转】【待调整】

    webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...

  7. 如何调用别人提供的webservice接口

    当我们拿到一个接口的时候,先别急着去调用它,我们得先测试这个接口是否正确,是否能调用成功,以及返回的数据是否是我们需要的类型等等.这时候我们需要一个工具,比如SoapUI.(最好用绿色免安装版的.)然 ...

  8. python使用suds调用webservice接口

    最近做接口对接,遇到了.net开发的webservice接口,因为python第一次与webservice对接,连问带查,最后使用suds库来实现了 1.安装suds mac: sudo pip in ...

  9. java实现https免证书认证

    java实现https免证书认证   解决方法: 1.下载两个包,httpclient-4.2.jar和httpcore-4.2.jar,复制以下代码就可使用. 2.调用类代码: String htt ...

随机推荐

  1. Mac系统下Datagrip打不开、点击没反应?

    有没有可能是因为你从网上下载了一些破解软件导致的? 背景 Mac系统下JB公司家的IDEA. Datagrip.PyCharm 或 Goland 打不开点击没反应-- 分析 大概率是之前安装过 汉化插 ...

  2. vue2和vue3的区别?

    vue2和vue3的主要区别在于以下几点: 1.生命周期函数钩子不同 2.数据双向绑定原理不同 3.定义变量和方法不同 4.指令和插槽的使用不同 5.API类型不同 6.是否支持碎片 7.父子组件之间 ...

  3. 项目实践2:(问卷)用html和css做一个网页

    好家伙,又来写项目了 1.以下是考题,姑且把他理解为甲方吧. 2.以下是附带的题目素材 开干.

  4. 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档

    背景 在计量领域中,计量检定是一种重要形式,主要用于评定计量器具的计量性能,确定其量值是否准确一致,实现手段包括计量检验.出具检定证书和加封盖印等. 在检定证书这一环节,存在一个难点,就是无法在线预览 ...

  5. Docker 完整版教程

    Docker 安装 一.安装前必读 在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可. 注意:本文的命令使用的是 roo ...

  6. [机器学习]-分类问题常用评价指标、混淆矩阵及ROC曲线绘制方法

    分类问题 分类问题是人工智能领域中最常见的一类问题之一,掌握合适的评价指标,对模型进行恰当的评价,是至关重要的. 同样地,分割问题是像素级别的分类,除了mAcc.mIoU之外,也可以采用分类问题的一些 ...

  7. Kibana:Canvas入门

  8. Elasticsearch中的一些重要概念:cluster, node, index, document, shards及replica

    首先,我们来看下一下如下的这个图: Cluster Cluster也就是集群的意思.Elasticsearch集群由一个或多个节点组成,可通过其集群名称进行标识.通常这个Cluster 的名字是可以在 ...

  9. linux系统排查数据包常用命令

    1.查看当前系统中生效的所有参数 sysctl -a 2.统计处于TIME_WAIT状态的TCP连接数 netstat -ant|grep TIME_WAIT|wc -l 3.统计TCP连接数 net ...

  10. PAT (Basic Level) Practice 1022 D进制的A+B 分数 20

    输入两个非负 10 进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数. 输入格式: 输入在一行中依次给出 3 个整数 A.B 和 D. 输出格式: 输出 A+ ...