使用WebService发布soap接口,并实现客户端的https验证
什么是https
HTTPS其实是有两部分组成:HTTP + SSL / TLS,
也就是在HTTP上又加了一层处理加密信息的模块,并且会进行身份的验证。
如何进行身份验证?
首先我们要明白什么是对称加密,什么是非堆成加密
对称加密
对称加密就是只有一个密钥,客户端双方按照约定的密钥对自己的明文进行加密。
但是这种方式有个很不好的情况。A和B通讯之前并不知道使用哪种密钥加密。所以在第一次通讯的时候会事先沟通好。
A->B:嗨!在吗?我们开始聊天吧。
B->A:好的,我们的密钥是:xxxxx。
如果此时黑客截取到了你的密钥,那加密也无济于事。
非对称加密
非对称加密就是在对称加密上再套一层公钥。所以有公钥和私钥两种形式。
A->B:嗨!在吗?我们开始聊天吧。
B->A:好的,我们的公钥是:xx。
A->B(以公钥:xx加密): 你好我是A,我们之后使用对称加密的zz来通讯。
B:以xx的密钥解密,得到密钥zz,之后双方通讯都通过对称加密的zz来通讯。
公钥是公开的,用公钥加密的信息只能使用密钥解密。公钥是解不开的,即便公钥被非法路由或黑客拦截,也不能通过公钥解密。这就是数学的魅力,有兴趣的话可以了解一下:RSA算法
这样就安全了?答案是否定的,如果在B->A发送公钥 xx 的时候就已经被非法路由器或者黑客拦截,然后向A发送偷天换日后的公钥 yy。此时非法路由就有两个公钥 xx 和 yy 。并且拥有有 yy 的私钥,因为 yy 是其自己生成的。
因此,当A收到非法路由发送过来的偷天换日后的公钥 yy ,A信以为真的认为这个就是B发送过来的公钥。当A向B发送发送一串由 YY 公钥加密的信息,非法路将其拦截并且用 yy 的密钥解密后再通过公钥 xx 加密后发送给B。这样你的消息通讯依旧是不安全的。
证书体系
上面这个环节按理来说已经很安全了,为什么还是会被黑客或者非法路由攻击?思考上面的环节,问题出在发送公钥的时候,被黑客拦截,然后偷天换日的换了一个公钥。那是不是只要保证公钥的不可更改,就能维护了呢?是的,证书的出现就是解决这个问题(也是为什么你要去找证书签发机构花钱购买证书的原因)!!
简单来说,一个HTTPS网站响应给我们的并不是一个公钥,而是证书。证书上包含了公钥,还包含了域名、签发机构、有效期、签名等等。
那证书的安全性怎么保证?为什么中间人不能做一个假证书?
因为这套证书体系已经根植于每一个操作系统里了。每一个操作系统里,都内置了数十张根证书,每个根证书都对应一个非常权威的证书签发机构。这些根证书上记录了各个机构的公钥。
那非法路由或者黑客能不能申请一个真的证书然后去做劫持呢?
通常来说,证书签发机构的审核非常严格,如果无法证明B这个域名属于他,签发机构是不会给他签发一个知乎域名的证书的。而如果中间人用了其他域名的证书,浏览器会发现你请求的域名和返回的证书不一致,从而拒绝继续请求。除非你一定要点下面的「仍然继续」:
最后无奈地说,在破解了这么多数学上的难题后,HTTPS的安全性仍然保证在『证书签发机构一定都是很有良心的』这种脆弱的基础上。(即便一些网站是通过证书签发机构的,但是嘛依旧会被植入小广告,咳咳....)。
实现客户端验证的WebService
我们了解了https和证书的作用。其实我们在系统之间内部通讯的时候就可以使用对称加密的方式进行访问即可。
因为是内部嘛,我们提前约定好使用何种证书就可以了。除非是很正式的项目,否则使用自己签发的证书即可,因为官方生成证书是要花钱滴。
有两种方式
第一种:服务端生成一个证书,每个客户端都生成自己的证书,然后让服务端与各个客户端相互信任。
第二种:生成一个证书,将这个证书派发给各个客户端,每个客户端携带该证书就会被服务端认证(这种安全性稍微低一些,但是在大部分对安全性要求不是特别高的场景推荐使用。下面主要说明这一种方式,如果想实现第一种参考:https://blog.csdn.net/u011350541/article/details/71941536)
生成证书
首先保证服务器有jdk,打开CMD工具,进入到jdk的bin目录下输入一下信息。如果配置了环境变量则直接在命令行中输入即可。
keytool -genkey -alias tomcat -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore D:/keys/server.jks -storepass 123456
上述参数的具体说明如下:
keytool
-genkey
-alias service(别名)
-keypass 123456(别名密码)
-keyalg RSA(算法)
-keysize 1024(密钥长度)
-validity 365(有效期,天单位)
-keystore D:/keys/server.jks(指定生成证书的位置和证书名称)
-storepass 123456(获取jks信息的密码)
发布的soap接口
/**
* @author Eric
* @Title: SoapService
* @date 2019/7/17 10:42
* @Description: 发布的soap接口,注意注释的使用
*/
@WebService
public interface SoapService {
void sayHello(@WebParam(name = "clientName") String clientName);
}
接口的具体实现类
/**
* @author Eric
* @Title: SoapServiceImpl
* @date 2019/7/17 10:42
* @Description: soap接口的具体实现,注意注释的使用
*/
@javax.jws.WebService
public class SoapServiceImpl implements SoapService {
@Override
public void sayHello(String clientName) {
System.out.println(clientName + "调用接口打了招呼");
}
}
发布soap接口
/**
* @author Eric
* @Title: testTest
* @date 2019/7/17 10:45
* @Description: 发布soap接口
*/
public class Release {
public static void main(String[] args) throws Exception {
initSoap();
}
//初始化soap接口
public static void initSoap() {
try {
String host = "0.0.0.0";
int port = 8888;
String address = "https://" + host + ":" + port + "/logProcessor"; //发布于https
JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
sf.setServiceClass(SoapService.class); //发布实现soap的接口类(你自己实现的接口,里面的方法就是发布的soap接口)
sf.setAddress(address);
SoapServiceImpl soapServiceImpl = new SoapServiceImpl(); //SoapService的实现类
sf.getServiceFactory().setInvoker(new BeanInvoker(soapServiceImpl));
sf = configureSSLOnTheServer(sf, port);
Server server = sf.create();
String endpoint = server.getEndpoint().getEndpointInfo().getAddress();
System.out.println("soap发布的地址为:" + endpoint);
} catch (Exception e) {
System.out.println("Soap初始化失败:"+e);
}
}
//https并且开启客户端认证。如果发布的接口是http,则无需实现该方法。
private static JaxWsServerFactoryBean configureSSLOnTheServer(JaxWsServerFactoryBean sf, int port) throws Exception {
TLSServerParameters tlsParams = new TLSServerParameters();
ClientAuthentication clientAuthentication = new ClientAuthentication();
clientAuthentication.setRequired(true); //开启客户端认证
tlsParams.setClientAuthentication(clientAuthentication);
KeyStore keyStore = KeyStore.getInstance("JKS");
String password = "123456"; //生成证书时候定义的的密码
File truststore = new File(Paths.get("D:\\keys", "server.jks").toString());
keyStore.load(new FileInputStream(truststore), password.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, password.toCharArray());
KeyManager[] km = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(km);
truststore = new File(Paths.get("D:\\keys", "server.jks").toString());
keyStore.load(new FileInputStream(truststore), password.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] tm = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(tm);
JettyHTTPServerEngineFactory factory = new JettyHTTPServerEngineFactory();
factory.setTLSServerParametersForPort(port, tlsParams);
}
}
使用soapUI模拟客户端调用soap接口
通过上述代码,我们将接口发布在了你自己定义的https://0.0.0.0:8888/logProcessor。如果发布成功,我们想远程调用soap接口,此时打开soapUI
- 选择左上角File然后选择Preferences。
- 选择SSL Settings,在KeyStore上导入我们生成的证书。否则无法远程调用(因为我们在代码中开启了客户端认证,如果没有开启可以跳过这一步)
- 然后返回主界面,创建soap,在弹出的界面中 ‘Project Name’可以自己定义。‘Initial WSDL’中输入你发布的地址加上‘?wsdl’如下:https://0.0.0.0:8888/logProcessor?wsdl
- 如果创建成功,你就能在左边看到自己项目中发布的接口。选择我们发布的接口sayHello,双击Request。
- 在弹出的界面中,将自己的参数输入,然后点击绿色三角形开始调用,因为我们这个方法没有参数返回,所有调用后没有什么信息会提示。
- 打开我们的ide,此时就能看到下面打印了一行话,说明方法调用成功
参考
https://zhuanlan.zhihu.com/p/37738632
https://blog.csdn.net/u011350541/article/details/71941536
使用WebService发布soap接口,并实现客户端的https验证的更多相关文章
- java调用C# webService发布的接口
java调用C# webService发布的接口 java调用C# webService方式有很多种我这里只介绍一种 首先需要引入axis的jar包 axis的maven坐标如下 <depend ...
- webservice发布服务:CXF及客户端调用
2.CXF:(与spring整合) CXF相对来说操作没有AXIS繁琐 1.导入spring的jar包和cxf的jar包 2.在spring的核心配置文件中配置发布的接口类 <?xml vers ...
- webservice发布服务:AXIS2及客户端调用
1.Axis2: 到官网下载axis2的压缩包. 解压后: 1.将lib文件下的jar包复制到项目中 2.在web-inf下创建services->META-INF->services.x ...
- WebService发布协议--SOAP和REST的区别
HTTP是标准超文本传输协议.使用对参数进行编码并将参数作为键值对传递,还使用关联的请求语义.每个协议都包含一系列HTTP请求标头及其他一些信息,定义客户端向服务器请求哪些内容,服务器用一系列HTTP ...
- 调用jersey发布的接口webservice,通过HttpPost传递文件
项目媒体文件之前都是上传到七牛云处理,现在客户为了安全和私密性,准备将移动端拍摄的图片和视频传递到文件服务器,所以就想办法能不能在服务器端发布一个WebService,供移动端调用.刚好之前做的接口都 ...
- 面向接口的webservice发布方式
import javax.jws.WebService; /**面向接口的webservice发布方式 */ @WebService public interface JobService { pub ...
- webservice发布接口
一:编写接口程序,计算功能类,有加减乘除四个方法 /** * */ package com.hlcui.util; /** * @author Administrator 将此类发布为公共接口 */ ...
- Web Service学习笔记(webservice、soap、wsdl、jws详细分析)
Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...
- WebService学习整理(一)——客户端三种调用方式整理
1 WebService基础 1.1 作用 1, WebService是两个系统的远程调用,使两个系统进行数据交互,如应用: 天气预报服务.银行ATM取款.使用邮箱账号登录各网站等. 2, ...
随机推荐
- 提示Windows Phone IP over USB Transport (IpOverUsbSvc)未运行,如何解决
原文:提示Windows Phone IP over USB Transport (IpOverUsbSvc)未运行,如何解决 uwp项目在安装测试时提示,"引导"Device&q ...
- MessageBox用法大全
//1.显示提示信息 MessageBox.Show("Hello World!"); //2.给消息框加上标题 MessageBox.Show("Hello World ...
- 国家气象局 天气预报 城市代码(JSON格式)
如题 { "城市代码": [ { "省": "北京", "市": [ { "市名": "北 ...
- MySQL 其它基本操作
索引 所谓索引,就是类似于书的目录,目的也类似,都是为了提高检索速度.ALTER TABLE <表名> ADD INDEX <索引名(列名)>;或者CREATE INDEX & ...
- qt5.7交叉编译gstreamer-1.0
一.交叉编译glib1.提前需先交叉编译libffiCC=/home/mjl/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc ...
- RoboVM 1.1 发布,Java 转原生平台代码
分享 <关于我> 分享 [中文纪录片]互联网时代 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...
- Openssl - Static libraries (w32, mingw) 以及对Qt静态编译时的设置
Openssl static libraries created for Windows 32bit using MinGW compiler Compiled with: ./Con ...
- 百度网盘背后的存储系统atlas
原文 http://www.bitstech.net/2015/07/25/baidu-atlas/ 百度网盘免费提供2TB存储, 它的存储量一定是惊人的, 支持它的存储系统atlas也是相当不 ...
- 设置Windows服务的访问权限
作者:beyond 默认情况下,只有管理员组成员.LocalSystem和Power Users组成员帐户才有权启动.停止服务.为了让普通用户也可以控制该服务,我们可以手动设置其访问权限.可能有些初学 ...
- Qt5 中对 C++11 一些新特性的封装
在 Qt5 中,提供更多 C++11 的特性支持,接下来我们将进行详细的说明. slots (槽) 的 Lambda 表达式 Lambda表达式 是 C++11 中的一个新语法,允许定义匿名函数.匿名 ...