`
Sev7en_jun
  • 浏览: 1225822 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
84184fc0-d0b6-3f7f-a3f0-4202acb3caf5
Apache CXF使用s...
浏览量:111322
社区版块
存档分类
最新评论

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

 
阅读更多

CXF 入门:HelloWorld接口发布

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
 

 

5
2
分享到:
评论
16 楼 a807966224 2018-02-07  
还是  多谢楼主  总结的挺好的 !!!
15 楼 a807966224 2018-02-07  
然后 通过 SOAPMessage.getHeader(qname); 取出相应的 header头信息,用来认证,这样可以避免从 SOAPMessage里取出多个头信息,  认证多次
14 楼 a807966224 2018-02-07  
我也是接触这东西不久,QName qname = new QName ("namespace路径", "localpart");
13 楼 a807966224 2018-02-07  
楼主     不知道你有没有出现 从headers 里取出来长度为2的头信息,   这样会在一次请求里  出现两次认证   很奇怪啊
12 楼 jiangwenxian 2013-10-29  
在log.info(userIdNodes.item(0) + "=" 
                    + userIdNodes.item(0).getTextContent());  报空指针异常
11 楼 lloWorld 2013-06-06  
您好,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>  这个如何生成的?
10 楼 q269223 2013-03-15  
Caused by: javax.xml.soap.SOAPException: SOAP消息头格式不对哦!
... 27 more
在客户端传输SOAPHeader的时候压根就没传过去。希望楼主可以解释一下。··
9 楼 Sev7en_jun 2012-11-04  
liuwuhen 写道
你好,楼主你的例子,实验成了吗?

测试ok的
8 楼 liuwuhen 2012-10-30  
你好,楼主你的例子,实验成了吗?
7 楼 liuxueping1987 2012-05-07  
按照楼主的操作做,在以下代码报异常。
if (null == headers || headers.size() < 1) {  
50.            throw new Fault(new SOAPException("SOAP消息头格式不对哦!"));  
51.        } 
6 楼 wenqxin 2012-01-14  
Sev7en_jun 写道
Sev7en_jun 写道
wenqxin 写道
为什么不通过wss4j 提供的回调类进行实现呢,cxf 已经实现了啊。配置会比这个简单


其实对于复杂程度都差不多一样,这个部分代码也可以直接通过配置来实现,这里是通过自定义的xml信息来校验,回调函数应该是定死了的


PS:不知道那种可以把安全级别设置更高一点??



wss4j 提供了不同安全级别的认证方式,常用的就是usernameToken(用户名和密码),你还可以通过授权文件等方式。
5 楼 Sev7en_jun 2012-01-13  
Sev7en_jun 写道
wenqxin 写道
为什么不通过wss4j 提供的回调类进行实现呢,cxf 已经实现了啊。配置会比这个简单


其实对于复杂程度都差不多一样,这个部分代码也可以直接通过配置来实现,这里是通过自定义的xml信息来校验,回调函数应该是定死了的


PS:不知道那种可以把安全级别设置更高一点??
4 楼 Sev7en_jun 2012-01-13  
wenqxin 写道
为什么不通过wss4j 提供的回调类进行实现呢,cxf 已经实现了啊。配置会比这个简单


其实对于复杂程度都差不多一样,这个部分代码也可以直接通过配置来实现,这里是通过自定义的xml信息来校验,回调函数应该是定死了的
3 楼 wenqxin 2012-01-13  
为什么不通过wss4j 提供的回调类进行实现呢,cxf 已经实现了啊。配置会比这个简单
2 楼 Sev7en_jun 2012-01-12  
baoyun618 写道
正想学习cxf呢,借楼主好文

过奖了,我也是参考网上资料做的,还很多不清楚 呵呵
1 楼 baoyun618 2012-01-12  
正想学习cxf呢,借楼主好文

相关推荐

    CXF使用EndpointImpl发布WebService加入拦截器

    本篇文章将深入探讨如何使用CXF的`EndpointImpl`类来发布一个WebService,并加入拦截器。 首先,我们要理解`EndpointImpl`是CXF框架用于构建和配置Web服务端点的核心类。通过实例化这个类,我们可以自定义服务的...

    CXF3.0+Spring3.2 自定义拦截器

    4. **拦截器链**:CXF允许你定义多个拦截器,形成一个处理链。当请求或响应通过这个链时,每个拦截器都有机会处理消息。如果某个拦截器抛出异常,链会被中断。 5. **自定义逻辑**:在自定义拦截器的`handleMessage`...

    CXF WebService带有拦截器

    CXF(CXF: The Apache CXF project)是一个开源的Java框架,专门用于构建和部署Web服务。本篇文章将深入探讨如何使用CXF来开发具有权限控制功能的Web Service,并通过拦截器实现这一目标。 首先,我们需要理解Web ...

    10.为CXF服务器端添加自定义拦截器进行权限检查

    首先,理解CXF(CXF: Apache CXF - A Next Generation JAXWS and JAX-RS API Implementation)是一个开源的Java框架,它用于创建和部署SOAP和RESTful Web服务。拦截器是CXF框架中的一种重要机制,它们允许我们在消息...

    CXF视频:1、使用CXF实现简单的HelloWorld

    【标题】"CXF视频:1、使用CXF实现简单的HelloWorld",这是一段关于Apache CXF框架的初级教程,旨在引导初学者通过实际操作理解如何利用CXF创建一个基本的“HelloWorld”服务。Apache CXF是一个开源的Java框架,它...

    CXF入门 -- 第一个简单webService

    本篇文章将带你入门CXF,通过创建一个简单的Web服务来理解其基本概念和工作流程。 1. **CXF简介** CXF全称CXF CXF (Common eXtensible Framework),它支持多种服务标准,如SOAP、RESTful、JAX-WS、JAX-RS等。CXF...

    13.为CXF与Spring整合发布WebService添加拦截器进行权限控制

    // 如果验证通过,继续执行下一个拦截器或服务方法 chain.doIntercept(message); } ``` 通过这种方式,我们可以灵活地在CXF和Spring集成的环境中添加权限控制,确保只有经过授权的用户才能访问Web服务。这不仅...

    cxf入门例子(安全认证)

    总之,"cxf入门例子(安全认证)" 是一个很好的起点,帮助初学者理解 CXF 如何处理 Web 服务的安全认证。通过学习这个例子,你将能够熟练地运用 CXF 创建安全的服务器端和客户端应用,同时也能够掌握如何配置和管理...

    cxf 入门(hello world)

    【描述】:这篇文章主要介绍如何使用Apache CXF框架进行Web服务开发,通过一个简单的“Hello World”示例来帮助初学者理解CXF的基本用法。 Apache CXF是一个开源的Java框架,主要用于构建和部署SOAP和RESTful Web...

    CXF源码:CXF_Spring源码

    CXF还可以利用Spring的AOP支持,为服务添加拦截器、过滤器等,实现事务管理、日志记录、安全控制等功能。 5. **异常处理** Spring可以帮助统一处理CXF服务抛出的异常,通过配置异常处理器,将服务层的异常转化为...

    08.CXF拦截器的理论以及如何为CXF的客户端和服务器端添加拦截器

    拦截器是CXF框架中的一个重要组成部分,允许开发者在服务调用的生命周期中插入自定义逻辑,实现如日志记录、安全检查、性能监控等功能。本篇将深入探讨CXF拦截器的理论基础,并演示如何为CXF的客户端和服务端添加...

    cxf入门使用代码展示

    2. 客户端调用:CXF提供了一种方便的客户端API,通过它,你可以创建一个服务代理,就像调用本地Java对象一样调用远程服务。 3. 数据绑定:CXF支持多种数据绑定机制,如JAXB,它可以自动将XML数据转换为Java对象,...

    CXF拦截器(Interceptor)的使用

    Apache CXF是一个开源框架,用于构建和消费基于SOAP和REST标准的Web服务。其设计的核心目标之一便是灵活性和可扩展性,这在很大程度上得益于其拦截器机制。拦截器允许开发者在请求和响应的消息传递过程中插入自定义...

    spring集成cxf客户端和服务器端demo(含自定义拦截器)

    在本项目中,"spring集成cxf客户端和服务器端demo(含自定义拦截器)"是一个实战案例,展示了如何在Spring框架下与Apache CXF服务进行整合,实现客户端和服务端的交互,并利用拦截器来增强功能。以下是这个项目涉及的...

    CXF和Spring整合,并且添加拦截器

    **标题:“CXF和Spring整合,并且添加拦截器”*...4. **添加拦截器**:CXF允许我们定义拦截器,以便在服务调用前后执行自定义逻辑。这可以通过在Spring配置文件中声明拦截器并将其绑定到Bus或Endpoint来实现。 ```xml ...

    CXF实现SSL安全验证

    ### CXF实现SSL安全验证 ...通过以上三个步骤,我们成功地实现了 CXF 的 SSL 安全验证,并搭建了一个基于 HTTPS 的 Web Service。这种方式不仅确保了数据传输的安全性,还提高了系统的整体安全等级。

    11.为CXF客户端添加自定义拦截器完成权限控制

    CXF是一个流行的开源框架,它支持SOAP和RESTful两种Web Service风格,并提供了丰富的功能,包括安全、拦截器等。本节我们将深入探讨如何为CXF客户端添加自定义拦截器以实现权限控制。 首先,理解拦截器的概念是至关...

    CXF3.1.16 +Spring4 +MyBatis + Maven自定义拦截器 WebService实例源码下载

    【标题解析】 ...这个项目提供了从设计、实现到测试Web服务的完整示例,对于学习和理解CXF、Spring、MyBatis和Maven的集成,以及如何在Web服务中实现自定义拦截器和安全验证机制,具有很高的参考价值。

    CXF发布WebService加入拦截器

    在Java世界中,Apache CXF是一个广泛使用的开源框架,它允许开发者创建和消费Web服务。当我们谈论"CXF发布WebService加入拦截器"时,这涉及到在CXF服务端和客户端增加拦截器来增强服务功能和控制流程。拦截器是CXF...

    Cxf拦截器实例

    例如,在Spring配置文件中,我们可以使用`&lt;cxf:client&gt;`或`&lt;cxf:endpoint&gt;`元素的`interceptor`属性来指定要使用的拦截器。 通过学习和理解这些示例,开发者可以更好地利用CXF拦截器来扩展和定制自己的Web服务,...

Global site tag (gtag.js) - Google Analytics