CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)
CXF拦截器使用,创建一个使用SOAPHeader的安全验证
xml格式:
<soap:Header>
<auth:authentication xmlns:auth="http://gd.chinamobile.com//authentication">
<auth:systemID>1</auth:systemID>
<auth:userID>test</auth:userID>
<auth:password>test</auth:password>
</auth:authentication>
</soap:Header>
一,首先在服务端创建一个拦截器(被调用端),需要继承org.apache.cxf.phase.AbstractPhaseInterceptor
代码如下:
import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList; /**
* 系统全局拦截器(排除登录服务调用) 用于校验登录的账号是否已登录
*
*/
public class AuthValidateInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private Logger logger = Logger.getLogger(this.getClass()); public AuthValidateInterceptor() {
// 定义拦截器阶段
super(Phase.PRE_INVOKE);
} /**
* @Description: 拦截器操作
* @param message
* 被拦截到的消息
* @throws Fault
*/
@Override
public void handleMessage(SoapMessage message) { List<Header> headers = message.getHeaders();
if (headers == null || headers.isEmpty()) {
throw new Fault(new Exception("无授权信息!"));
} Element auth = null;
// 获取授权信息元素
for (Header header : headers) {
QName qname = header.getName();
String tagName = qname.getLocalPart();
if (tagName != null && tagName.equals("auth")) {
auth = (Element) header.getObject();
break;
}
} // 如果授权信息元素不存在,提示错误
if (auth == null) {
throw new Fault(new Exception("无授权信息!"));
} NodeList nameList = auth.getElementsByTagName("username");
NodeList pwdList = auth.getElementsByTagName("password");
if (nameList.getLength() != 1 || pwdList.getLength() != 1) {
throw new Fault(new Exception("授权信息错误!"));
} String name = nameList.item(0).getTextContent();
String password = pwdList.item(0).getTextContent();
if (!"admin".equals(name) || !"admin".equals(password)) {
throw new Fault(new Exception("授权信息错误!"));
}
} }
二,修改cxf-beans.xml <!--id:随意配,implementor:指定接口具体实现类,address:随意配,访问时会用到,下面会做说明-->
<!--拦截器-->
<bean id="authIntercetpr" class="unitTest.AuthIntercetpr"></bean>
<jaxws:endpoint id="HelloWorldService" implementor="com.ws.HelloWorldServiceImpl"
address="/IHelloService">
<!-- 在此配置调用当前ws所触发的拦截器-->
<jaxws:inInterceptors><ref bean="authIntercetpr" /></bean>
<!--或者直接在这里写<bean class="unitTest.AuthIntercetpr"></bean>-->
</jaxws:inInterceptors>
</jaxws:endpoint> 到此服务端工作完毕!!!
下面是客户端(调用端)
三,这边同样创建一个拦截器,实现org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor
import java.util.List; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element; /**
* 系统全局拦截器(排除登录服务调用) 用于校验登录的账号是否已登录
*
*/
public class ClientAuthValidateInterceptor extends AbstractSoapInterceptor { private Logger logger = Logger.getLogger(this.getClass()); public static final String xml_namespaceUR = "";
public static final String xml_header = "soap:Header";
public static final String xml_authentication = "auth:authentication";
public static final String xml_systemID = "auth:systemID";
public static final String xml_username = "auth:username";
public static final String xml_password = "auth:password"; public ClientAuthValidateInterceptor() {
// 定义拦截器阶段
super(Phase.WRITE);
} /**
* @Description: 拦截器操作
* @param message
* 被拦截到的消息
* @throws Fault
*/
@Override
public void handleMessage(SoapMessage message) { String userId = "test";
String sysId = "1";
String password = "test"; Document doc = DOMUtils.createDocument();
Element root = doc.createElement(xml_header); Element eSysId = doc.createElement(xml_systemID);
eSysId.setTextContent(sysId); Element eUserId = doc.createElement(xml_username);
eUserId.setTextContent(userId); Element ePwd = doc.createElement(xml_password);
ePwd.setTextContent(password); Element child = doc.createElementNS(xml_namespaceUR, xml_authentication);
child.appendChild(eSysId);
child.appendChild(eUserId);
child.appendChild(ePwd); root.appendChild(child); QName qname = new QName("RequestSOAPHeader");
SoapHeader head = new SoapHeader(qname, root);
List<Header> headers = message.getHeaders();
headers.add(head); } }
四,具体调用ws的类代码
HelloWorldServiceImplService hello = new HelloWorldServiceImplService();
HelloWorldService service = hello.getHelloWorldServiceImplPort(); // 插入身份验证
Client clientProxy = ClientProxy.getClient(port);// 通过目标ws获取代理
// 注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发
clientProxy.getOutInterceptors().add(new ClientAuthValidateInterceptor());
// 超时时间设置
HTTPConduit http = (HTTPConduit) clientProxy.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(Integer.valueOf("6000"));
httpClientPolicy.setReceiveTimeout(Integer.valueOf("6000"));
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
//下面这行代码是具体调用服务段的deleteTeskTask()
CallResult cResult = service.deleteTeskTask("1223");
五,还有一种方式是通过JaxWsProxyFactoryBean方式,注册拦截器及实例化ws,代码如下:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
List<Interceptor<? extends Message>> clientAuthValidateInterceptors = new ArrayList<>();
// 添加soap header 信息
clientAuthValidateInterceptors.add(new ClientAuthValidateInterceptor());
// 注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发
factory.setOutInterceptors(clientAuthValidateInterceptors);
factory.setServiceClass(HelloWorldService.class);// 实例化ws
factory.setAddress("http://localhost:8090/iwm/sapDeliveryOrderToIwm");
Object obj = factory.create();
HelloWorldService service = (HelloWorldService) obj;
//下面这行代码是具体调用服务段的deleteTeskTask()
CallResult cResult = service.deleteTeskTask("1223");
客户端代码到此结束
CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)的更多相关文章
- CXF 入门:创建一个基于WS-Security标准的安全验证(CXF回调函数使用,)
http://jyao.iteye.com/blog/1346547 注意:以下客户端调用代码中获取服务端ws实例,都是通过CXF 入门: 远程接口调用方式实现 直入正题! 以下是服务端配置 ==== ...
- 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包
MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性,它使得我们可以用 C# 语言编写扩展:利用这种扩展性,我们可以为我们的项目定制一部分的编译细节.NuGet 为我们提供了一种自 ...
- 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...
- 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- 如何创建一个基于 .NET Core 3 的 WPF 项目
在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF:同时还发布了 Visual Studio 2019 预览版 ...
- 扩展一个boot的插件—tooltip&做一个基于boot的表达验证
在线演示 本地下载 (代码太多请查看原文) 加班,加班加班,我爱加班··· 我已经疯了,哦也. 这次发一个刚接触boot的时候用boot做的表单验证,我们扩展一下tooltip的插件,让他可以换颜色. ...
- 基于注解风格的Spring-MVC的拦截器
基于注解风格的Spring-MVC的拦截器 Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是Defa ...
- SharePoint入门——创建一个网站
1.首先安装SP相关环境,可以百度到具体操作步骤: (以下步骤基于本人环境:本人用的Win10自带的Hyper-V虚拟机.Windows Server2012R2.SQL2014以及SharePoin ...
- javascript创建一个基于数组的栈结构
栈是一种遵从后进先出(LIFO)原则的有序集合.新添加或待删除的元素都保存在栈的同 一端,称作栈顶,另一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底. 栈拥有以下方法: push(eleme ...
随机推荐
- bootstrap设计站点中加入�代码高亮插件
这款插件的名字叫做google-code-prettify 使用该插件之前的效果: 使用插件之后的效果: 接下来说步骤: (1)下载两个文件 http://codecloud.sinaapp.com/ ...
- Kafka目录
1. kafka生产者.消费者java示例 2. apache kafka监控系列-KafkaOffsetMonitor(转) 3. Kafka0.8.2删除topic逻辑(转) 4. spark s ...
- datagridview 单元格类型转换【备忘】
datagridview 在设定列类型后,其下面所有行的该列都与设定的列类型相同. 在需要改变某一行的某个单元格时,遇到了一些问题,再次进行备忘: 之前在遇到该问题时参考别人的博客解决过,但是时间久 ...
- 数学图形(2.26) 3D曲线结
我收集的几种曲线结 knot(huit) #http://www.mathcurve.com/courbes3d/noeuds/noeudenhuit.shtml vertices = 1000 t ...
- liunx修改字体为宋体
有找到修改Linux默认字体的方法sudo vi /etc/fonts/conf.d/69-language-selector-zh-cn.conf修改下sans-serif相关设定 <m ...
- javaScript几个操作数组增减元素的函数
1. shift:删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined 2. unshift:将参数添加到原数组开头,并返回数组的长度 var a = [1,2,3,4,5]; ...
- python 相似语句匹配(非机器学习)
#coding=utf-8 import xlrd import distance from sklearn.feature_extraction.text import CountVectorize ...
- public类型中internal成员
今天遇到一问题,找到下面的两篇文章,研究比较深入,特转了一下, 最近除了搞ASP.NET MVC之外,我也在思考一些编程实践方面的问题.昨天在回家路上,我忽然对一个问题产生了较为清晰的认识.或者说,原 ...
- cscope无法索引代码树之外的软链接
http://blog.csdn.net/sudolee/article/details/9052291 背景:为什么非要使用cscope?不用ctags? 尽管ctags可以索引软链接,但是,cta ...
- 关于ibatis的实体类部分属性无法映射
今天在编码中不小心就遇到了一个ibatis初学者偶尔会遇到的问题. 先来看这张图中的DictionPo的部分属性赋值都为空.其实,数据库中是有数据的. 再来看看mapper的写法 上面那个对象查询语句 ...