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拦截器使用)的更多相关文章

  1. CXF 入门:创建一个基于WS-Security标准的安全验证(CXF回调函数使用,)

    http://jyao.iteye.com/blog/1346547 注意:以下客户端调用代码中获取服务端ws实例,都是通过CXF 入门: 远程接口调用方式实现 直入正题! 以下是服务端配置 ==== ...

  2. 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包

    MSBuild 的 Task 为我们扩展项目的编译过程提供了强大的扩展性,它使得我们可以用 C# 语言编写扩展:利用这种扩展性,我们可以为我们的项目定制一部分的编译细节.NuGet 为我们提供了一种自 ...

  3. 如何创建一个基于命令行工具的跨平台的 NuGet 工具包

    命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...

  4. 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  5. 如何创建一个基于 .NET Core 3 的 WPF 项目

    在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF:同时还发布了 Visual Studio 2019 预览版 ...

  6. 扩展一个boot的插件—tooltip&做一个基于boot的表达验证

    在线演示 本地下载 (代码太多请查看原文) 加班,加班加班,我爱加班··· 我已经疯了,哦也. 这次发一个刚接触boot的时候用boot做的表单验证,我们扩展一下tooltip的插件,让他可以换颜色. ...

  7. 基于注解风格的Spring-MVC的拦截器

    基于注解风格的Spring-MVC的拦截器 Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是Defa ...

  8. SharePoint入门——创建一个网站

    1.首先安装SP相关环境,可以百度到具体操作步骤: (以下步骤基于本人环境:本人用的Win10自带的Hyper-V虚拟机.Windows Server2012R2.SQL2014以及SharePoin ...

  9. javascript创建一个基于数组的栈结构

    栈是一种遵从后进先出(LIFO)原则的有序集合.新添加或待删除的元素都保存在栈的同 一端,称作栈顶,另一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底. 栈拥有以下方法: push(eleme ...

随机推荐

  1. easyui radio 取值和赋值

    1.html文件 <td><input id="client" type="text" name="client" sty ...

  2. [Android Studio] Android Studio移除的Module如何恢复(转载)

    如果你执行了从module列表中移除module的操作,但是没有执行delete module文件夹的操作,那如何恢复被移除掉的module呢. 关于如何移除请戳这:Android Studio如何删 ...

  3. nose的setup和teardown

    参考:http://blog.csdn.net/linda1000/article/details/8533349 1.模块的setUp和tearDown def setUp(): print &qu ...

  4. qsort(),sort()排序函数

    一.qsort()函数 功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp ...

  5. Single Number and Single Number II

    [] Given an array of integers, every element appears twice except for one. Find that single one. [] ...

  6. 【Linux】shell中svn报错:svn: Can't convert string from 'UTF-8' to native encoding:xxx

    解决办法: shell中svn命令之前添加: #!/bin/bash export LC_ALL=en_US.UTF- export LANG=en_US.UTF- export LANGUAGE=e ...

  7. TortoiseSVN 源代码下载

    SVN的客户端软件TortoiseSVN http://tortoisesvn.tigris.org/ 这是我采用的 TortoiseSVN 的官方网站,页面上的两只小乌龟真的很好看. 目前最新的版本 ...

  8. MySQL截取字符串函数方法

    函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...

  9. 算法笔记_134:字符串编辑距离(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 给定一个源串和目标串,能够进行如下操作: 在任意位置上插入一个字符: 替换掉任意字符: 删除任意字符. 写一个程序,实现返回最小操作次数,使得对源串 ...

  10. Git 提示fatal: remote origin already exists

    Git 提示fatal: remote origin already exists 错误解决办法 最后找到解决办法如下: 1.先删除远程 Git 仓库 $ git remote rm origin 2 ...