CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)

下面具体的webservice实现类直接用的是上面的,这里不再说明

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.soap.SOAPException;  

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.XMLUtils;
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 AuthIntercetpr extends AbstractPhaseInterceptor<SoapMessage> {
    private static final Logger logger = Logger.getLogger(AuthIntercetpr.class);
    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";
    public static final String xml_header_el = "soap:Header";
    public static final String xml_authentication_el = "auth:authentication";
    public static final String xml_systemID_el = "auth:systemID";
    public static final String xml_userID_el = "auth:userID";
    public static final String xml_password_el = "auth:password";
    public AuthIntercetpr() {
        // 指定该拦截器在哪个阶段被激发
        super(Phase.PRE_INVOKE);
    }  

    // 处理消息
    public void handleMessage(SoapMessage message) {
        logger.info("==================SoapMessage =" + message);
        // 获取SOAP消息的全部头
        List<Header> headers = message.getHeaders();  

        if (null == headers || headers.size() < 1) {
            throw new Fault(new SOAPException("SOAP消息头格式不对哦!"));
        }
        for (Header header : headers) {
            SoapHeader soapHeader = (SoapHeader) header;
            // 取出SOAP的Header元素
            Element element = (Element) soapHeader.getObject();
            logger.info("ELEMENT =" + element.toString());
            XMLUtils.printDOM(element);
            NodeList userIdNodes = element
                    .getElementsByTagName(xml_userID_el);
            NodeList pwdNodes = element
                    .getElementsByTagName(xml_password_el);
            NodeList systemIdNodes = element
                    .getElementsByTagName(xml_systemID_el);
            logger.info("############ 打印帐号信息 ##############");
            logger.info(userIdNodes.item(0) + "="
                    + userIdNodes.item(0).getTextContent());
            logger.info(systemIdNodes.item(0) + "="
                    + systemIdNodes.item(0).getTextContent());
            logger.info(pwdNodes.item(0) + "="
                    + pwdNodes.item(0).getTextContent());
            logger.info("############————————##############");
            if (null != userIdNodes
                    && userIdNodes.item(0).getTextContent().equels("test") ) {
                if (null != pwdNodes
                        && pwdNodes.item(0).getTextContent().equals("test")) {
                    logger.info("$$$$$$$$ 认证成功");
                } else {//认证失败则抛出异常,停止继续操作
                    SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");
                    throw new Fault(soapExc);
                }
            } else {//认证失败则抛出异常,停止继续操作
                SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");
                throw new Fault(soapExc);
            }  

        }
    }
}

二,修改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.text.SimpleDateFormat;
import java.util.Date;
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.helpers.XMLUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;  

public class AddSoapHeader extends AbstractSoapInterceptor {  

    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";
    public static final String xml_header_el = "soap:Header";
    public static final String xml_authentication_el = "auth:authentication";
    public static final String xml_systemID_el = "auth:systemID";
    public static final String xml_userID_el = "auth:userID";
    public static final String xml_password_el = "auth:password";  

    public AddSoapHeader() {
    // 指定该拦截器在哪个阶段被激发
        super(Phase.WRITE);
    }  

    public void handleMessage(SoapMessage message) throws Fault {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String time = sd.format(date);
        String userId = "test";
        String sysId = "1";
        String password = "test";  

        QName qname = new QName("RequestSOAPHeader");//这个值暂时不清楚具体做什么用,可以随便写  

        Document doc = (Document) DOMUtils.createDocument();
        Element root = doc.createElement(xml_header_el);
        Element eSysId = doc.createElement(xml_systemID_el);
        eSysId.setTextContent(sysId);
        Element eUserId = doc.createElement(xml_userID_el);
        eUserId.setTextContent(userId);
        Element ePwd = doc.createElement(xml_password_el);
        ePwd.setTextContent(password);
        Element child = doc.createElementNS(xml_namespaceUR_att,
                xml_authentication_el);
        child.appendChild(eSysId);
        child.appendChild(eUserId);
        child.appendChild(ePwd);
        root.appendChild(child);
        XMLUtils.printDOM(root);// 只是打印xml内容到控制台,可删除
        SoapHeader head = new SoapHeader(qname, root);
        List<Header> headers = message.getHeaders();
        headers.add(head);  

    }  

}

四,具体调用ws的类代码

private static final String webServiceConTimeout = "6000";
private static final String webServiceRevTimeout = "6000";  

HelloWorldServiceImplService hello = new HelloWorldServiceImplService();
HelloWorldService service = hello.getHelloWorldServiceImplPort();
//以上什么意思请参考:http://learning.iteye.com/admin/blogs/1333223
Client clientProxy = ClientProxy.getClient(service);//通过目标ws获取代理
//注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发
clientProxy.getOutInterceptors().add(ash);
// 超时时间设置
HTTPConduit http = (HTTPConduit) clientProxy.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(Integer
		.valueOf(webServiceConTimeout));
httpClientPolicy.setReceiveTimeout(Integer
		.valueOf(webServiceRevTimeout));
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
//以上插入点超时设置方式
//下面这行代码是具体调用服务段的deleteTeskTask()
CallResult cResult = service.deleteTeskTask("1223");

客户端代码到此结束

五,还有一种方式是通过JaxWsProxyFactoryBean方式,注册拦截器及实例化ws,代码如下:

private static final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  

AddSoapHeader ash = new AddSoapHeader();
ArrayList list = new ArrayList();
// 添加soap header 信息
list.add(ash);
//注入拦截器,getOutInterceptors代表调用服务端时触发,getInInterceptors就是被调用才触发
 factory.setOutInterceptors(list);
 factory.setServiceClass(HelloWorldService.class);//实例化ws
 factory.setAddress("http://xxx.xxx.xxx.xxx:8004/services/IHelloService");
 Object obj = factory.create();
 HelloWorldService service = (HelloWorldService) obj;
 //下面这行代码是具体调用服务段的deleteTeskTask()
CallResult cResult = service.deleteTeskTask("1223");

##########这段代码可替代步骤(四)#####

到此全部工作结束

具体一些概念还请自己baidu/google

时间: 2024-08-04 23:40:34

CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)的相关文章

Kivy A to Z -- 如何从Python创建一个基于Binder的Service及如何从Java访问Python创建的Service

<Kivy A to Z -- 如何从python代码中直接访问Android的Service> 一文中讲到了如何从python访问java的service,这一篇再来讲下如何创建一个基于Binder的Python Service以及如何从Java代码中访问这个Python创建的Service. 先来看代码,再作下解释: 接<Kivy A to Z -- 如何从python代码中直接访问Android的Service>一文,我们在相关的文件中增加代码: binder_wrap.cp

使用CXF+spring创建一个web的接口项目

一.web project整合spring 1.1.打开Myeclipse,建立web project(eclipse为dynamic web project),使用J2EE5.0. 1.2.添加Srping的基本jar包(无需事务等) org.springframework.beans-3.1.1.RELEASE.jar commons-logging.jar org.springframework.aop-3.1.1.RELEASE.jar org.springframework.asm-3

如何创建一个基于Maven的SmartGWT项目

如何创建一个基于Maven的SmartGWT项目 使用环境 Eclipse的版本为:Luna Service Release 2 (4.4.2)(这个其实不是很重要,你完全可以使用最新版本的Eclipse或者MyEclipse) Maven的版本为:3.1.0 SmartGWT的版本为:6.0p GWT的SDK版本为:2.7 前提准备 你需要安装Maven.如何安装Maven不是文本的内容,你可以参考我的关于Maven的博客. 把SmartGWT的jar包上传到私服服务器. 操作过程 创建GWT

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

在线演示 本地下载 (代码太多请查看原文) 加班,加班加班,我爱加班··· 我已经疯了,哦也. 这次发一个刚接触boot的时候用boot做的表单验证,我们扩展一下tooltip的插件,让他可以换颜色. 其实挺简单的,主要是考究代码阅读的能力. boot的代码写的很简单,能省略“;”的地方就省略掉了,而且他的闭包也很有意思 +function($){ }(jQuery); 这种写法等同于 (function($){ })(jQuery); 少些一个符号,比较节俭. 他的对外接口写的就比较正常了:

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

基于注解风格的Spring-MVC的拦截器 Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter: < bean class ="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerM

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

注意:以下客户端调用代码中获取服务端ws实例,都是通过CXF 入门: 远程接口调用方式实现 以下是服务端配置 ======================================================== 一,web.xml配置,具体不在详述 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.

[STM32F10x] 从零开始创建一个基于标准库的工程

硬件:STM32F103C8T6 平台:MDK-AMR V4.70 1.创建一个Keil uVision 的工程 要点:相同类型的源文件放在一起以便于管理       2.添加标准库源文件 3.添加几个必要的源文件 包括: core_cm3.c stm32f10x_it.c system_stm32f10x_it.c stm32f10x_conf.h 4.指定头文件路径 5.添加必要的预处理标志 本例为 USE_STDPERIPH_DRIVER, STM32F10X_MD 6.添加一个main函

【webGL】threejs入门 ---创建一个简单立方体

开发环境 Three.js是一个JavaScript库,所以,你可以使用平时开发JavaScript应用的环境开发Three.js应用.如果你没什么偏好的话,我会推荐Komodo IDE. 调试建议使用Chrome或者Firefox浏览器.如果你使用的是Firefox,那么Firebug会是你必不可少的插件:如果你使用的是Chrome,那么直接使用控制台调试即可.这些和JavaScript的调试是相同的,因此本书不作进一步展开. 下载 首先,我们需要在Github下载Three.js的代码. 在

Qt使用教程之创建一个基于Qt部件的应用程序(一)

<Qt Enterprise最新版下载> 本教程主要介绍了如何使用Qt Creator来创建一个文字搜索的小的Qt应用程序,它是Qt UI Tools Text Finder Example的简化版本.该应用程序的用户界面是由Qt部件使用Qt Designer构建的:在代码编辑器中使用C ++编写该应用程序的逻辑. 创建文本搜索项目 1. 选择File > New File or Project > Application > Qt Widgets Application &