博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cxf+spring+数字签名开发webservice(一)
阅读量:6985 次
发布时间:2019-06-27

本文共 9446 字,大约阅读时间需要 31 分钟。

  • 数字证书的准备

        下面做的服务端和客户端证书在例子中无法加解密,不知道什么原因,我是使用正式环境中的客户端和服务端进行开发测试的,所以需要大家自己去准备证书,或者有人知道为什么jdk生成的一对证书无法加解密的原因那在好不过了。(例子中客户端和服务端都放在一起项目中,大家自己分开开发测试即可)下面是我用jdk生成的证书:

        1.1、客户端             

               1、创建私钥和keystore

                    keytool -genkey -alias clientprivatekey -keypass keypass -keystore client.jks -storepass storepass -dname "CN=zs.com,C=CN" -keyalg RSA
               2、自签名
                    keytool -selfcert -keystore client.jks -storepass storepass -alias clientprivatekey -keypass keypass
               3、导出公钥到rsa
                    keytool -export -alias clientprivatekey -file client.rsa -keystore client.jks -storepass storepass 

         1.2、服务端              

               1、创建私钥和keystore

                    keytool -genkey -alias serverprivatekey -keypass keypass -keystore server.jks -storepass storepass -dname "CN=zs.com,C=CN" -keyalg RSA
               2、自签名
                    keytool -selfcert -keystore server.jks -storepass storepass -alias serverprivatekey -keypass keypass
               3、导出公钥到rsa
                    keytool -export -alias serverprivatekey -file server.rsa -keystore server.jks -storepass storepass

         1.3、将服务端公钥加入客户端jks中

                keytool -import -alias serverprivatekey  -file server.rsa -keystore client.jks -storepass storepass

         1.4、将客户端公钥加入服务端jks中

                keytool -import -alias clientprivatekey -file client.rsa -keystore server.jks -storepass storepass


 

  • 证书配置文件

         2.1、客户端配置

               jks文件放在ca包下,ca包直接在项目的src目录下,配置文件名称为client.properties(放在ca下),注意等号两边不要出现空格     

1 org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin 2 org.apache.ws.security.crypto.merlin.keystore.type=jks 3 org.apache.ws.security.crypto.merlin.keystore.password=证书的storepass4 org.apache.ws.security.crypto.merlin.keystore.alias=证书的别名5 org.apache.ws.security.crypto.merlin.file=ca/client.jks

         2.2、服务端配置

               jks文件放在ca包下,ca包直接在项目的src目录下,配置文件名称为server.properties(放在ca下),注意等号两边不要出现空格

1 org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin 2 org.apache.ws.security.crypto.merlin.keystore.type=jks 3 org.apache.ws.security.crypto.merlin.keystore.password=storepass4 org.apache.ws.security.crypto.merlin.keystore.alias=serverprivatekey5 org.apache.ws.security.crypto.merlin.file=ca/server.jks

  • 秘钥配置类

         3.1、客户端

 

1 package cxf.test.client; 2  3 import java.io.IOException; 4 import javax.security.auth.callback.Callback; 5 import javax.security.auth.callback.CallbackHandler; 6 import javax.security.auth.callback.UnsupportedCallbackException; 7 import org.apache.ws.security.WSPasswordCallback; 8  9 public class UTPasswordClientCallBack implements CallbackHandler {10 11     @Override12     public void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException {13        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];14        pc.setPassword("证书的keypass");15        System.out.println("Client Identifier=" + pc.getIdentifier());16        System.out.println("Client Password=" + pc.getPassword());17     }18 19 }

 

         3.2、服务端

1 package cxf.test.server; 2  3 import java.io.IOException; 4  5 import javax.security.auth.callback.Callback; 6 import javax.security.auth.callback.CallbackHandler; 7 import javax.security.auth.callback.UnsupportedCallbackException; 8  9 import org.apache.ws.security.WSPasswordCallback;10 11 public class UTPasswordServerCallBack implements CallbackHandler {12 13     @Override14     public void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException {15        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];16        pc.setPassword("证书的keypass");17        System.out.println("Client Identifier=" + pc.getIdentifier());18        System.out.println("Client Password=" + pc.getPassword());19     }20 21  }

  • 配置文件

        4.1、web.xml配置

 

1 
2
contextConfigLocation
3
WEB-INF/beans.xml
4
5
6
org.springframework.web.context.ContextLoaderListener
7
8
9
CXFServlet
10
org.apache.cxf.transport.servlet.CXFServlet
11
12
13
CXFServlet
14
/services/*
15

 

         4.2、beans.xml配置(spring配置文件)

1 
2
5
6
7
8
9
10
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

  • 服务端类

 

 

        5.1、接口类

1 package cxf.test.server; 2  3 import javax.jws.WebParam; 4 import javax.jws.WebService; 5  6 //配置targetNamespace,不进行配置,将使用当前类所在的包名顺序反向(如果这里没设置,默认命名空间为:http://server.test.cxf/)为命名空间。 7 //不进行命名空间设置,会存在客户端和服务端需要保持包名一致的问题,这在现实开发中肯定是很麻烦的事 8 @WebService(name = "TestWebService", targetNamespace = "http://cxf.test.tns/") 9 public interface TestWebService {10     // 为了更好的兼容不同的开发语言、jdk版本等,接口方法的参数和返回结果最好是字符串,对象按xml格式进行编写和解析11     // 接口方法的参数最好使用annotation设定接口方法的参数名,不进行设置,默认会在参数前加上“{”等符号(具体符号可能有误),12     // 这样可能会给客户端调用带来不必要的麻烦,cxf有好几个annotation配置,如果客户端和服务端传递数据复杂类型参数时出现null等情况,一般进行相应annotation配置即可13     public abstract String testMethod(@WebParam(name = "xml") String xml);14 }

        5.2、接口实现类

1 package cxf.test.server;2 3 4 public class TestWebServiceImpl implements TestWebService {5     public String testMethod(String xml) {6         System.out.println(xml);7         return "服务端被调用";8     }9 }
  • 客户端类

        6.1、接口类

1 package cxf.test.client; 2  3 import javax.jws.WebParam; 4 import javax.jws.WebService; 5  6 //使用annotation设置接口的命名空间。如果不进行设置,会出现客户端和服务端的接口类和bean类所在包名需保持一致的问题。出现对象作为参数 7 //或返回结果时为null的情况,不进行设置,默认按包名的反向顺序(如果该接口方法不进行设置,默认命名空间为:http://server.test.cxf/)作为命名空间 8 //最好是设置命名空间,包名暴露也不是好事 9 @WebService(name = "TestWebService", targetNamespace = "http://cxf.test.tns/")10 public interface TestWebService {11     // 为了更好的兼容不同的开发语言、jdk版本等,接口方法的参数和返回结果最好是字符串,对象按xml格式进行编写和解析12     // 接口方法的参数最好使用annotation设定接口方法的参数名,不进行设置,默认会在参数前加上“{”等符号(具体符号可能有误),13     // 这样可能会给客户端调用带来不必要的麻烦14     public abstract String testMethod(@WebParam(name = "xml") String xml);15 }

         6.2、公共方法

1 package cxf.test.client; 2  3 import java.util.HashMap; 4 import java.util.Map; 5 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; 6 import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; 7 import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; 8  9 /**10  * 客户端调用服务端公共类11  * 12  * @author yu13  * 14  */15 public class Client {16     /**17      * 调用服务端接口时,先调用该方法,获得服务端接口方法,该方法设置数字签名的加解密信息18      * 19      * @param address20      *            wsdl地址,包含“?wsdl”后缀21      * @return22      */23     public TestWebService call(String address) throws Exception {24         JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();25         factory.setServiceClass(TestWebService.class);26         factory.setAddress(address);27         Map
properties = new HashMap
();28 properties.put("mtom-enabled", Boolean.TRUE);29 factory.setProperties(properties);30 // 客户端请求服务端时,客户端进行签名和加密,对应服务端请求拦截器。31 Map
outProps = new HashMap
();32 outProps.put("action", "Signature Encrypt");33 outProps.put("user", "85e46503a2958c9137b832ebca4ee304_e9c397b2-2e69-4de0-8183-e978aa23b1d5");// 客户端证书别名34 outProps.put("passwordCallbackClass",35 UTPasswordClientCallBack.class.getName());36 outProps.put("encryptionUser", "9598de1694450bdbe56ff58d7fa55cb9_e9c397b2-2e69-4de0-8183-e978aa23b1d5");// 服务端证书别名37 outProps.put("encryptionPropFile", "ca/client.properties");// 客户端证书配置信息38 outProps.put("signatureUser", "85e46503a2958c9137b832ebca4ee304_e9c397b2-2e69-4de0-8183-e978aa23b1d5");// 客户端证书别名39 outProps.put("signaturePropFile", "ca/client.properties");40 WSS4JOutInterceptor outInterceptor = new WSS4JOutInterceptor(outProps);41 outInterceptor.setAllowMTOM(true);42 factory.getOutInterceptors().add(outInterceptor);43 // 服务端响应客户端请求时,客户端对服务端签名和加密进行处理,对应服务端响应拦截器44 Map
inProps = new HashMap
();45 inProps.put("action", "Signature Encrypt");46 inProps.put("passwordCallbackClass",47 UTPasswordClientCallBack.class.getName());48 inProps.put("decryptionPropFile", "ca/client.properties");49 inProps.put("signaturePropFile", "ca/client.properties");50 factory.getInInterceptors().add(new WSS4JInInterceptor(inProps));51 TestWebService webService = (TestWebService) factory.create();52 return webService;53 }54 55 }

          6.3、测试    

1 package cxf.test.client; 2  3 public class TestClient { 4     // 服务端wsdl地址,包含"?wsdl"后缀,wsdl地址一般放在数据库等地方,方便服务端改动时,客户端好更改. 5     private static String address = "http://127.0.0.1:7001/cxfserver/services/wstest?wsdl"; 6  7     public static void main(String[] args) { 8         try { 9             Client client = new Client();10             TestWebService webService = client.call(address);11             String result = webService.testMethod("客户端调用服务端");12             System.out.println(result);13         } catch (Exception e) {14             e.printStackTrace();15         }16     }17 }
  • 说明

        如果webservice的方法参数和返回值是xml(即将对象编写成xml作为参数传递),可以使用JiBx对对象和xml之间的转换做操作,可以参考下面文章:

              http://www.ibm.com/developerworks/cn/java/tutorials/j-jibx1/

转载于:https://www.cnblogs.com/yuyuj/p/4526514.html

你可能感兴趣的文章
python中的数据类型,存储,实现
查看>>
.htaccess FollowSymlinks影响rewrite功能
查看>>
201671010117 2016-2017-2 《Java程序设计》Java第二周学习心得
查看>>
编程语言的概念
查看>>
App_Offline.htm 一个静态页面实现整站维护时统一页面
查看>>
create-react-app部署到GitHub Pages时报错:Failed to get remote。origin.url
查看>>
TypeScript入门知识五(面向对象特性二)
查看>>
TextBox字符串转换为数字类型
查看>>
HTML5的可视化开发工具Maqetta Designer
查看>>
leetcode 29. Divide Two Integers
查看>>
axis调用webservice客户端开发
查看>>
Activiti5第八弹,ProcessEngineConfiguration和ProcessEngine
查看>>
细说C#多线程那些事 - 线程同步和多线程优先级
查看>>
单例模式
查看>>
发送验证码倒计时
查看>>
程序员看中的浏览器
查看>>
浙大pat甲级题目---1021. Deepest Root (25)
查看>>
CCRD_TOC_2008年第2期
查看>>
脊柱关节病外周关节滑膜高表达的RANK/RANKL/OPG系统与炎症呈部分分离
查看>>
vue Cli 脚手架的搭建
查看>>