CXF 集成wss4j
项目需求对webservice接口进行加密,然后网上看到wss4j,于是翻阅资料写的歌DEMO
首先JAR包引入
<!-- CXF 3.2.4 START--><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-spring-boot-starter-jaxws</artifactId><version>3.2.6</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-ws-security</artifactId><version>3.2.6</version></dependency>
然后服务端CXF的配置类
import com.aadata.datacenter.dataManage.webservice.MessagePackService;
import org.apache.cxf.Bus;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.xml.ws.Endpoint;
import java.util.HashMap;
import java.util.Map;@Configuration
public class CxfConfig {@Autowiredprivate MessagePackService messagePackService;// 注意:要修改ServletRegistrationBean的别名,如果不修改会和前端控制器的Servlet名称冲突,导致spring找不到相应的servlet@Bean(name="CXFServlet")public ServletRegistrationBean dispatcherServlet() {return new ServletRegistrationBean(new CXFServlet(), "/webservice/*");// 发布服务名称 localhost:8080/webservice}@Bean(name = Bus.DEFAULT_BUS_ID)public SpringBus springBus() {return new SpringBus();}@Beanpublic Endpoint getDataManageServer() {EndpointImpl endpoint = new EndpointImpl(springBus(), messagePackService);Map<String, Object> inProps = new HashMap<String, Object>();inProps.put(WSHandlerConstants.USER, "admin");inProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);//加密类型inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); //密码类型为加密inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,ExampleServiceInterceptor.class.getName()); //密码回调函数endpoint.getInInterceptors().add( new SAAJInInterceptor());endpoint.getInInterceptors().add(new WSS4JInInterceptor(inProps));endpoint.publish("/CommonService");return endpoint;}}
服务端的拦截器
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import javax.security.auth.callback.CallbackHandler;public class ExampleServiceInterceptor implements CallbackHandler {private Map<String, String> passwords = new HashMap<String, String>();public ExampleServiceInterceptor() {passwords.put("admin1", "password1");//验证信息:用户名+密码,必须与客户端一致才可验证通过}public void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException {for (int i = 0; i < callbacks.length; i++) {WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];String identifier = pc.getIdentifier();//用户名int usage = pc.getUsage();//验证方式if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKENpc.setPassword(passwords.get(identifier));}else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATUREpc.setPassword(passwords.get(identifier));}}}}
客户端拦截器
import org.apache.wss4j.common.ext.WSPasswordCallback;
import java.util.HashMap;
import java.util.Map;import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;public class ExampleServiceClientInterceptor implements CallbackHandler {private Map<String, String> passwords = new HashMap<String, String>();public ExampleServiceClientInterceptor() {passwords.put("admin1", "password1");}public void handle(Callback[] callbacks) {for (int i = 0; i < callbacks.length; i++) {WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];String identifier = pc.getIdentifier();int usage = pc.getUsage();if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKENpc.setPassword(passwords.get(identifier));/}else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATUREpc.setPassword(passwords.get(identifier));}}}
}
客户端调用主方法
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;import javax.xml.namespace.QName;import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.handler.WSHandlerConstants;public class test020 {public static void main(String[] args) throws Exception {JaxWsDynamicClientFactory dcflient=JaxWsDynamicClientFactory.newInstance();Client client=dcflient.createClient("http://localhost:8999/webservice/CommonService?wsdl");Map<String, Object> outProps = new HashMap<String, Object>();outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN);outProps.put(WSHandlerConstants.USER, "admin1");outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);// 指定在调用远程ws之前触发的回调函数WsClinetAuthHandler,其实类似于一个拦截器outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,ExampleServiceClientInterceptor.class.getName());ArrayList list = new ArrayList();// 添加cxf安全验证拦截器,必须list.add(new SAAJOutInterceptor());list.add(new WSS4JOutInterceptor(outProps));client.getOutInterceptors().addAll(list);QName name=new QName("http://webservice.dataManage.datacenter.aadata.com/","sayHello");Object[] objects=client.invoke(name,"wss4j+cxf实现WS-Security");System.out.println(objects[0].toString());}
}
CXF方式生成客户端调用
CXF 客户端生成client对象命令:
C:\Users\Administrator\Downloads\apache-cxf-3.2.6\bin> wsdl2java -p com.aadata -d C:\Users\Administrator\Desktop\test -client http://192.168.2.20:8088/WSSSS/webservice/CommonService/sayHello?wsdl
对应的客户端拦截器
import org.apache.wss4j.common.ext.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import java.util.HashMap;
import java.util.Map;public class ExampleServiceClientInterceptor implements CallbackHandler {private Map<String, String> passwords = new HashMap<String, String>();public ExampleServiceClientInterceptor() {passwords.put("HuQiuTest", "Ceshi_123456");}public void handle(Callback[] callbacks) {for (int i = 0; i < callbacks.length; i++) {WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];String identifier = pc.getIdentifier();int usage = pc.getUsage();if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKENSystem.out.println(passwords.containsKey(identifier)+"="+passwords.get(identifier)+"-"+identifier);pc.setPassword(passwords.get(identifier));// //▲【这里非常重要】▲}else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATUREpc.setPassword(passwords.get(identifier));// //▲【这里非常重要】▲}}}
}
对应客户端类(WSHandlerConstants.ACTION值有所修改,对应服务端也要修改):
package wsss;/*** Please modify this class to meet your needs* This class is not complete*/import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.handler.WSHandlerConstants;import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;/*** This class was generated by Apache CXF 3.2.6* 2021-01-22T15:14:43.233+08:00* Generated source version: 3.2.6**/
public final class MessagePackService_MessagePackServiceImplPort_Client {private static final QName SERVICE_NAME = new QName("http://webservice.dataManage.datacenter.aadata.com/", "MessagePackService");private MessagePackService_MessagePackServiceImplPort_Client() {}public static void main(String args[]) throws Exception {URL wsdlURL = wsss.MessagePackService_Service.WSDL_LOCATION;if (args.length > 0 && args[0] != null && !"".equals(args[0])) {File wsdlFile = new File(args[0]);try {if (wsdlFile.exists()) {wsdlURL = wsdlFile.toURI().toURL();} else {wsdlURL = new URL(args[0]);}} catch (MalformedURLException e) {e.printStackTrace();}}wsss.MessagePackService_Service ss = new wsss.MessagePackService_Service(wsdlURL, SERVICE_NAME);wsss.MessagePackService port = ss.getMessagePackServiceImplPort();org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);Endpoint cxfEp = client.getEndpoint();Map<String, Object> outProps = new HashMap<String, Object>();outProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN+" "+WSHandlerConstants.TIMESTAMP);outProps.put(WSHandlerConstants.USER, "Test");outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);// 指定在调用远程ws之前触发的回调函数WsClinetAuthHandler,其实类似于一个拦截器outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,wsss.ExampleServiceClientInterceptor.class.getName());cxfEp.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));{System.out.println("Invoking sayHello...");String _sayHello_userName = "测试方法";String _sayHello__return = port.sayHello(_sayHello_userName);System.out.println("sayHello.result=" + _sayHello__return);}System.exit(0);}}
CXF 集成wss4j相关推荐
- spring和CXF集成来实现webservices
最近在负责一个大系统的实施,经过需求分析之后,将系统分为5个子系统,我们采用SOA架构,分模块开发.项目组中最大的一个争议就是,子系统之间的通讯问题,大家提出了两种方案:一.如果5个子系统最后发布为5 ...
- 一个CXF集成SPRING的WEBSERVICE完整实例
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 1 首先 ...
- SpringCloud工作笔记079---SpringBoot中使用CXF集成SpringWebServices_来创建wsdl_WebServices_服务端_以及客户端
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 1.创建springboot项目,创建webservice 其实直接不选择,直接点击next也行, ...
- CXF与Web项目集成---without Spring
1.CXF集成web项目,是通过org.apache.cxf.transport.servlet.CXFNonSpringServlet进行集成 2.servlet Java代码 public ...
- 在cxf中使用配置避免增加字段导致客户端必须更新、同步实体属性的问题
在使用cxf实现webservice时,经常碰到的问题就是如果在服务端,修改了一个接口的签名实现,如增加一个字段,或者删除一个字段.在这种情况下,在默认的配置中,就会报以下的错误信息: org.apa ...
- 【转】使用Apache CXF开发WebServices服务端
原地址:http://cnjava.blog.51cto.com/1208887/335630 在前一篇的博客中,我使用Xfire1.x来开发了WebServies的服务端. 但是如果你访问Apach ...
- java cxf 工具_利用CXF工具开发WebService接口
简单记录一下webservice接口开发以便供以后参考: 一.根据需求编写wsdl文件 WSDL的文件格式和语法我就不多说了,到网上百度一下,或者到W3CSchool去学习都可以,语法很简单,下面是我 ...
- 个人觉得这篇cxf的文章还不错
CXF实战(一) 原创 2015年07月27日 11:23:08 标签: CXF / WebService / 20550 编辑 删除 Apache CXF提供了用于方便地构建和开发WebServic ...
- wsld2java_脱离spring集成cxf(基于nutz框架)
什么是webService cxf 简单的说就是实现webService的一个比较流行的框架 http://blog.sina.com.cn/s/blog_6182547f01017pak.html ...
最新文章
- Linux System Programming --Chapter Seven
- 设计模式---(创建型)单例模式
- 相对于硬件计算机软件就是,计算机的软件是将解决问题的方法,软件是相对于硬件来说的...
- leecode5 最长回文子串
- petalinux 2020.2 安装教程,基于ubuntu20.04.LTS版本
- 用友NC总账辅助余额表与应收应付模块余额表对账技巧
- 黑马程序员_Java基础_枚举 和 单例模式实例
- 一个非常强大的视频、音频、二维码、图片、压缩等在线网址
- dojo基础:dojo/request
- WPS Office应用大全
- 写一函数,实现两个字符串的比较。即自己写一个strcmp函数,函数原型为int strcmp(char * p1 ,char * p2); 设p1指向字符串s1, p2指向字符串s2。要求当s1=s2
- 串口之DCB结构体详解
- android生成图片不失真,Android的PdfRenderer类生成低质量图像
- 济南近郊出游——线路指南
- Modbus协议(翻自wiki)
- 数据驱动运营,为门店开拓第二增长曲线。
- 进阶高级自动化测试测试,Docker 常遇问题整理(带解决方案)
- 「次时代建模」次时代游戏模型制作教程
- compareAndSwapObject
- 不出千元!打造耐用、高效SCSI硬盘系统(转)