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 ...
随机推荐
- sed替换换行符“\n”
linux sed命令,如何替换换行符“\n” 在一次sed使用中,执行命令: sed "s/\n//g" file 1 发现,没起到任何效果. 后来,经查sed官方用户手册,才得 ...
- sharememory.c
//进程通信,共享存储区 #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #i ...
- Spark应用程序运行的日志存在哪里(转)
原文链接:Spark应用程序运行的日志存在哪里 在很多情况下,我们需要查看driver和executors在运行Spark应用程序时候产生的日志,这些日志对于我们调试和查找问题是很重要的. Spark ...
- JNI字段描述符
“([Ljava/lang/String;)V” 它是一种对函数返回值和参数的编码.这种编码叫做JNI字段描述符(JavaNative Interface FieldDescriptors).一个数组 ...
- PHP-Java-Bridge使用笔记
最近因为需要封装一个jar包供php调用,在网上搜索了下,基本上讲都是使用php-java-bridge,说实话,网上的教程有很多是不行的,但是功夫不负有心人,找到了一篇文章,也很感谢那篇文章的作者, ...
- 今天才知道的JavaScript的真实历史~[转]
JavaScript真的继承自Cmm吗?JavaScript与Java有多少关系?JavaScirpt最初的设计是怎样的?这个文章是从一个叫编程人生的网站上看到的.不知道出处在哪.在许多资料,Java ...
- java设计模式2--抽象工厂模式(Abstract Factory)
本文地址:http://www.cnblogs.com/archimedes/p/java-abstract-factory-pattern.html,转载请注明源地址. 抽象工厂模式(别名:配套) ...
- 【论文笔记】Leveraging Datasets with Varying Annotations for Face Alignment via Deep Regression Network
參考文献: Zhang J, Kan M, Shan S, et al. Leveraging Datasets With Varying Annotations for Face Alignment ...
- iOS 图片比例缩放
方法 //Resize image - (UIImage *)resizeImage:(UIImage *)image withQuality:(CGInterpolationQuality)qual ...
- Struts完美解决i18n问题
所谓的i18n问题指的是(软件的)国际化问题,简单来讲就是使我们的软件可以让世界使用任何语言的人们都能使用,软件自身会根据语言环境的不同进行自动配置,如果你是中文环境那界面以中文显示,如果是英文环境就 ...