`
erichua
  • 浏览: 516397 次
  • 性别: Icon_minigender_2
  • 来自: 远方
社区版块
存档分类
最新评论

CXF学习笔记---给CXF加一把锁WS_SECURITY应用

阅读更多
CXF的webService已经创建好,但没有安全可言,毕竟这是Internet服务呀。
CXF给了一个很完整的安全架构,但CXF给出的ws_security DEMO太复杂了,又是password jks X509 Timestamp。 我试了很多次都没有成功。化繁为简,只实现一个user password好了。其实CXF和Spring——ACEGI的认证机制很像的都是使用了intercetor。
下面开始
编写cxf.xml在原来的bean的地方声明一下就可以了
	<bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken" />
				<entry key="passwordType" value="PasswordText" />
				<entry key="passwordCallbackClass"
					value="com.mms.webservice.test.ServerPasswordCallback" />
			</map>
		</constructor-arg>
	</bean>

<jaxws:endpoint id="helloWorld"
		implementor="com.mms.webservice.HelloWorldImpl"
		address="/HelloWorld">
		<jaxws:inInterceptors>
		<!-- 
			<bean
				class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
			<bean
				class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
				<constructor-arg>
					<map>
						<entry key="action" value="UsernameToken" />
						<entry key="passwordType" value="PasswordText" />
						<entry key="passwordCallbackClass"
							value="com.mms.webservice.test.ServerPasswordCallback" />
					</map>
				</constructor-arg>
			</bean>
			 -->
			 <ref bean="WSS4JInInterceptor" />
		</jaxws:inInterceptors>
	</jaxws:endpoint>

WSS4JInInterceptor就是我们要定义的东东了。CXf已经帮你写好了。设置属性就可以了。里面属性值挺多的,CXF的文档就是太简单了,opensource的弊病!属性值就查API吧。
下面需要写server端的密码回调函数,验证logic就在这里定义了。
package com.mms.webservice.test;

import java.io.IOException;
import java.util.ResourceBundle;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class ServerPasswordCallback implements CallbackHandler {

	private static final String BUNDLE_LOCATION = "com.mms.webservice.test.pass";
	private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";

	private static String password;
	static {
		final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
		password = bundle.getString(PASSWORD_PROPERTY_NAME);
	}

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {

		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];

		// Set the password on the callback. This will be compared to the
		// password which was sent from the client.
		// We can call pc.getIdentifer() right here to check the username
		// if we want each client to have it's own password.
		if (pc.getIdentifer().equalsIgnoreCase("eric")) {
			if (!pc.getPassword().equals(password)) {
				throw new SecurityException("wrong password");
			}
		}
		else
		{
			throw new SecurityException("the user does not exits");
		}

	}

}


就此server端的验证就全部ok了。这时再调用原来的调用程序就会报ws_security错误了。

下面给出Client验证程序
其实就是在soapheader上加相应内容。也需要用到inInterceptors
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.tnt.mms.webservice.client;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tnt.mms.webservice.VendorMaintenance;
import com.tnt.mrm.model.other.Vendor;

public final class ClientVendor {

	private ClientVendor() {
	}

	public static void main(String args[]) throws Exception {
		// START SNIPPET: client
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "com/tnt/mms/webservice/client/client-vendor-beans.xml" });

		try {

			VendorMaintenance client = (VendorMaintenance) context
					.getBean("client");

			Vendor ls = client.get("10116");
			System.out.println("Response: " + ls.getEngName());

			List<Vendor> rs = client.getList();
			System.out.println("Response: " + rs.size());
			System.out.println("Response: " + rs.get(0).getEngName());

			System.exit(0);

		} catch (Exception e) {

			e.printStackTrace();
			System.out.println("error" + e.getMessage());

		}
	}
}



client_vendor_beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
	Licensed to the Apache Software Foundation (ASF) under one
	or more contributor license agreements. See the NOTICE file
	distributed with this work for additional information
	regarding copyright ownership. The ASF licenses this file
	to you under the Apache License, Version 2.0 (the
	"License"); you may not use this file except in compliance
	with the License. You may obtain a copy of the License at
	
	http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing,
	software distributed under the License is distributed on an
	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
	KIND, either express or implied. See the License for the
	specific language governing permissions and limitations
	under the License.
-->
<!-- START SNIPPET: beans -->
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
	<!-- Configure CXF to use Aegis data binding instead of JAXB -->
	<bean id="aegisBean"
		class="org.apache.cxf.aegis.databinding.AegisDatabinding"
		scope="prototype" />
	<bean id="jaxwsAndAegisServiceFactory"
		class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
		scope="prototype">
		<property name="dataBinding" ref="aegisBean" />
		<property name="serviceConfigurations">
			<list>
				<bean
					class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration" />
				<bean
					class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration" />
				<bean
					class="org.apache.cxf.service.factory.DefaultServiceConfiguration" />
			</list>
		</property>
	</bean>

	<bean id="client" class="com.mms.webservice.VendorMaintenance"
		factory-bean="clientFactory" factory-method="create" />

	<bean id="clientFactory"
		class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass"
			value="com.mms.webservice.VendorMaintenance" />
		<property name="address"
			value="http://localhost:8080/extjsmms/services/VendorMaintenance" />
		<!-- 	<property name="serviceFactory" ref="jaxwsAndAegisServiceFactory"/> -->
		<property name="inInterceptors">
			<list>
				<ref bean="logIn" />
			</list>
		</property>
		<property name="outInterceptors">
			<list>
				<ref bean="logOut" />
				<ref bean="saajOut" />
				<ref bean="wss4jOut" />
			</list>
		</property>
	</bean>


	<bean id="logIn"
		class="org.apache.cxf.interceptor.LoggingInInterceptor" />
	<bean id="logOut"
		class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	<bean id="saajOut"
		class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
	<bean id="wss4jOut"
		class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken" />
				<entry key="user" value="eric" />
				<entry key="passwordType" value="PasswordText" />
				<entry key="passwordCallbackClass"
					value="com.mms.webservice.client.ClientPasswordCallback" />
			</map>
		</constructor-arg>
	</bean>
</beans>
<!-- END SNIPPET: beans -->

至此验证成功。后面将研究timestamp的验证方法。
2
5
分享到:
评论
5 楼 zqb666kkk 2015-10-29  
能提供下示例demo吗
4 楼 itcyt 2011-12-29  
用cxf-rest怎么加上安全认证?
3 楼 erichua 2008-11-08  
read the property from the file that is stored in the class path. you could find the example on the cxf source site.
2 楼 weixinjie 2008-10-30  
还有就是想问一下楼主:ServerPasswordCallback 类里面的
private static final String BUNDLE_LOCATION = "com.mms.webservice.test.pass";  
    private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";  
 
    private static String password;  
    static {  
        final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);  
        password = bundle.getString(PASSWORD_PROPERTY_NAME);  
    }  
的作用是什么?能解释一下么
谢谢
1 楼 weixinjie 2008-10-30  
楼主你好:
   我配置好之后..WSDL文档能出来..但是在测试的时候出现以下错误信息,请楼主指点:

2008-10-30 15:40:19 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be /wsHello
2008-10-30 15:40:19 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be /wsDemo
2008-10-30 15:40:20 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
信息: Interceptor has thrown exception, unwinding now
org.w3c.dom.DOMException: No such Localname for SOAP URI
	at org.apache.axis.message.SOAPDocumentImpl.createElementNS(SOAPDocumentImpl.java:379)
	at org.apache.axis.SOAPPart.createElementNS(SOAPPart.java:1109)
	at org.apache.cxf.staxutils.W3CDOMStreamWriter.writeStartElement(W3CDOMStreamWriter.java:98)
	at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.writeSoapEnvelopeStart(SoapOutInterceptor.java:98)
	at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:79)
	at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:60)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:466)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251)
	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
	at $Proxy43.say(Unknown Source)
	at com.icafe.test.WebServiceTest.main(WebServiceTest.java:25)
Exception in thread "main" java.lang.NoSuchMethodError: javax.xml.soap.SOAPFault.setFaultCode(Ljavax/xml/namespace/QName;)V
	at org.apache.cxf.jaxws.JaxWsClientProxy.createSoapFault(JaxWsClientProxy.java:203)
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
	at $Proxy43.say(Unknown Source)
	at com.icafe.test.WebServiceTest.main(WebServiceTest.java:25)

相关推荐

    Apache_cxf_学习笔记

    Apache CXF 是一个开源的...本学习笔记将继续深入探讨CXF的高级特性,如消息处理、安全控制、异常处理等,并提供更多的实战案例来帮助读者更好地理解和应用Apache CXF。在实践中不断探索,将助你成为CXF的熟练使用者。

    Apache_cxf_学习笔记.docx

    ### Apache CXF 学习笔记知识点汇总 #### 一、CXF简介 ##### 1.1 CXF概述 - **背景介绍**:Apache CXF 是一个高性能、功能丰富的开源框架,用于构建和消费 Web 服务。它融合了 Celtix 和 XFire 两个开源项目的...

    CXF学习笔记.docx )

    CXF(CXF: Composite eXtensible Framework)是一个开源的Java框架,它主要用于构建和服务导向架构(Service-Oriented Architecture, SOA)中的Web服务。CXF允许开发者通过多种方式来创建和消费Web服务,无论是基于...

    Axis2,CXF版本学习笔记

    文件“WebService_CXF学习.doc”和“axis2_WebService_开发指南.docx”、“axis_WebService_-_开发指南.docx”应该包含了关于这两个框架的详细教程和实践案例,可以帮助你更深入地理解和应用它们。 总的来说,Axis2...

    Apache cxf 学习笔记.pdf

    Apache CXF 是一个开源的Java框架,它主要用于构建和开发服务导向架构(Service-Oriented Architecture, SOA)的应用程序。CXF这个名字来源于两个曾经流行的Java Web服务项目的合并:Celtix和XFire,CXF意在强调其对...

    CXF的学习笔记

    CXF 包含了大量的功能特性,但是主要集中在以下几个方面: 支持 Web Services 标准:CXF 支持多种 Web Services 标准,包含 SOAP、Basic Profile、WS-Addressing、WS-Policy、WS-ReliableMessaging 和 WS-Security。...

    CXF webservice初学笔记

    【CXF Webservice初学笔记】 Apache CXF 是一个开源的 Web 服务框架,它允许开发者创建和消费各种类型的 Web 服务。CXF 整合了 XFire 和 Celtix 两个项目,提供了一套全面的工具和服务接口,支持 SOAP、RESTful、WS...

    CXF笔记

    【CXF笔记】是关于Apache CXF框架的深入学习记录,这个笔记可能涵盖了CXF的基本概念、使用方法、源码解析以及与开发工具的结合应用。Apache CXF是一个开源服务框架,它允许开发者构建和消费各种Web服务。下面将详细...

    cxf学习笔记之结合spring创建客户端

    **CXF** 是一个强大的Web服务框架,它支持SOAP、RESTful等多种服务样式,并提供了丰富的功能,如WSDL第一和第二类生成、WS-Security、MTOM等。CXF使得开发和部署Web服务变得更加简单。 **Spring** 是一个企业级Java...

    CXF与Spring整合基础学习笔记

    【CXF与Spring整合基础学习笔记】 在Java企业级开发中,Apache CXF是一个非常流行的开源服务框架,它用于构建和开发服务,支持多种Web服务标准。而Spring框架则是Java应用开发的核心框架,提供了一个全面的编程和...

    Java+WebService利用(cxf)开发笔记.rar

    在"Java+WebService利用(cxf)开发笔记"中,你将找到这些概念的实际应用和案例,帮助你深入理解如何使用CXF创建和调用Web服务。这份笔记是学习和实践的宝贵资料,不仅可以帮助初学者快速上手,也能为有经验的开发者...

Global site tag (gtag.js) - Google Analytics