前言

在调用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. 输入a、b、c三个整数,按先大后小的顺序输出a、b和c。注意请使用指针变量的方式进行比较和输出。

    `void swap(int *a,int *b,int c){ if(a < *b){ int temp = *a; //防止temp没有初始化 随机存放地址指向系统工作区间 可以对temp初 ...

  2. Html飞机大战(三):定义状态

    好家伙, 1.为飞机大战定义状态 1.开始 START 有一个飞机大战LOGO &天空 2.开始时 STRATING 有一个飞机加载的界面&天空 3.运行时 RUNNING 我方飞机& ...

  3. SpringMvc(一)-初识

    1.环境搭建 1.1 jar包 <spring.version>4.3.18.RELEASE</spring.version> <!-- spring-mvc begin ...

  4. LyScript 内存扫描与查壳实现

    LyScript 中提供了多种内存特征扫描函数,每一种扫描函数用法各不相同,在使用扫描函数时应首先搞清楚他们之间的差异,如下将分别详细介绍每一种内存扫描函数是如何灵活运用的,最后将实现一个简易版内存查 ...

  5. ProxySQL 读写分离方法

    转载自:https://www.jianshu.com/p/597b840bf70c (使用正则表达式实现基本的读/写分离) 在这一部分,我将通过一个示例来演示如何通过正则表达式来实现读/写分离. 首 ...

  6. 创建多个节点的集群 - Elastic Stack 8.0

    文章转载自:https://mp.weixin.qq.com/s/k6u9Q2nebW9qgZMghQwJng 详述如何安装3个节点的 Elasticsearch 集群.我将使用 Docker 来进行 ...

  7. PPR管的熔接

    1. 热熔器的介绍 2. 用热熔器熔接PPR管

  8. 使用 fail2ban 和 FirewallD 黑名单保护你的系统

    如果你运行的服务器有面向公众的 SSH 访问,你可能遇到过恶意登录尝试.本文介绍了如何使用两个实用程序来防止入侵者进入我们的系统. 为了防止反复的 ssh 登录尝试,我们来看看 fail2ban.而且 ...

  9. MySQL数据库-数据表(上)

    数据表的基本操作. MySQL 数据库支持多种数据类型,大致可以分为 3 类:数值类型.日期和时间类型.字符串(字符)类型. (1)数值类型 数值类型用于存储数字型数据,这些类型包括整数类型(TINY ...

  10. NSIS V3.08 简体中文增强版

    说明: 该3.08版本属本人业余时间集成修改制作,首发博客园,欢迎反馈安装与使用中出现的BUG,转载请注明出处! 本版本母版源自NSIS(Nullsoft Scriptable Install Sys ...