`
han_zw
  • 浏览: 174412 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

基于CXF的webservice的鉴权

    博客分类:
  • java
阅读更多

参照上一篇博文 基于HTTPS的webservice 的环境搭建step by step 完成所需环境之后,就可以开始接下来的著名项目HelloWorld了。
1.    建立一个helloworld的web项目
2.    创建SEI

package com.harvey.services;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(targetNamespace="http://webservice.harvey.com")
public interface HelloWorldInf {
	public String sayHello(@WebParam(name="name")String name);
}

 通过@WebService注解将该接口声明为webservice

3.    创建SIB

package com.harvey.services;

import javax.jws.WebService;

@WebService(endpointInterface="com.harvey.services.HelloWorldInf",
targetNamespace="http://webservice.harvey.com")
public class HelloWorldImpl implements HelloWorldInf {
	public String sayHello(String name) {
		return "hello,"+name;
	}
}

 这个类功能虽然很强大,但是应该比较容易看懂,就是向调用者打招呼。

4.    建立鉴权的handler

package com.harvey.services;

import java.io.IOException;

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 {

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
		String pw = pc.getPassword();
		String idf = pc.getIdentifier(); 
		
		if (!"harvey".equals(idf) || !"123456".equals(pw)) {
			throw new SecurityException("鉴权失败!");
		}
	}

}

 5.    通过spring整合
通过spring发布helloworld服务并为服务添加鉴权的handler.
在web.xml的配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:/applicationContext.xml</param-value>
	</context-param>
	 
	 <listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	 <servlet>
	 	<servlet-name>CXFServlet</servlet-name>
	 	<servlet-class>
	 		org.apache.cxf.transport.servlet.CXFServlet
	 	</servlet-class>
	 	<load-on-startup>1</load-on-startup>
	 </servlet>

	 <servlet-mapping>
	 	<servlet-name>CXFServlet</servlet-name>
	 	<url-pattern>/services/*</url-pattern>
	 </servlet-mapping>
	 <welcome-file-list>
	 	<welcome-file>index.jsp</welcome-file>
	 </welcome-file-list>
</web-app>

 为了方便直接在src目录下建立applicationContext.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:cxf="http://cxf.apache.org/core"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
	
	xsi:schemaLocation="
	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
	http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 
	<bean id="hello" class="com.harvey.services.HelloWorldImpl" />
	<jaxws:endpoint  id="helloworldservice" 
		endpointName="e:helloWorldPointName" 
		serviceName="s:helloworldservice" 
		implementor="#hello"  
		address="/helloworld"
		xmlns:e="http://webservice.harvey.com/endponit"
		xmlns:s="http://webservice.harvey.com/service">
		
		<jaxws:inInterceptors>  
             <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">  
                 <constructor-arg>  
                     <map>  
                         <entry key="action" value="UsernameToken" />  
                         <entry key="passwordType"  
                             value="PasswordText" />  
                         <entry key="user" value="cxfServer" />  
                         <entry key="passwordCallbackRef">  
                             <ref bean="serverPasswordCallback" />  
                         </entry>  
                     </map>  
                 </constructor-arg>  
             </bean>  
         </jaxws:inInterceptors>  
	</jaxws:endpoint>
	
	<bean id="serverPasswordCallback"   class="com.harvey.services.ServerPasswordCallback" />
</beans>

 Server端的工作就这些了,结合我们在上一篇文章中提到的数字证书的环境,一个支持数字证书和鉴权的server端搭建完成了。
接下来我们在转到client端,看一下如何在client加入对数字证书以及鉴权的支持。

 

6.    创建client端的密码的handler
为了方便起见,我们不再为client独立创建功能,与service在同一项目下建立client端的回调类,为webservice的请求添加鉴权的头信息

import java.io.IOException;

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 ClientPasswordCallback implements CallbackHandler {

	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        pc.setPassword("123456");
        pc.setIdentifier("Harvey");
	}

}

 

7.    创建client的spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:cxf="http://cxf.apache.org/core"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:http="http://cxf.apache.org/transports/http/configuration"
	xmlns:sec="http://cxf.apache.org/configuration/security"
	
	xsi:schemaLocation="
	http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd 
	http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd 
	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
	http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<bean id="client" class="com.harvey.services.HelloWorldInf"
		factory-bean="clientFactory" factory-method="create" />

	<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass" value="com.harvey.services.HelloWorldInf" />
		<property name="address" value="https://localhost:8443/WebServiceDemo/services/helloworld" />
         <property name="outInterceptors">  
             <list>  
                 <ref bean="wss4jOut" />  
             </list>  
         </property>  
	</bean>
	<bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="UsernameToken" />
				<entry key="user" value="cxfClient" />
				<entry key="passwordType" value="PasswordText" />
				<entry key="passwordCallbackClass" value="com.harvey.services.ClientPasswordCallback" />
			</map>
		</constructor-arg>
	</bean>
</beans>

 8.    创建client端的测试类,并将上一篇 博文中生成的client.jks和truststore.jks添加到类目录下

package com.harvey.test;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.harvey.services.HelloWorldInf;

public class HelloWorldClient {
	private final static String trustStore = "truststore.jks";
	private final static String keyStore = "client.jks";
	private final static String trustStorePass = "123456";
	private final static String keyStorePass = "999999";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		ApplicationContext context=new ClassPathXmlApplicationContext("client-bean.xml");
		HelloWorldInf client = (HelloWorldInf)context.getBean("client");
		
		Client proxy = ClientProxy.getClient(client);   
        HTTPConduit conduit = (HTTPConduit) proxy.getConduit();    
        TLSClientParameters tlsParams = conduit.getTlsClientParameters();
        
        if (tlsParams == null) {
            tlsParams = new TLSClientParameters();
        }
        tlsParams.setSecureSocketProtocol("SSL");
        tlsParams.setKeyManagers(getKeyManagers());
        tlsParams.setTrustManagers(getTrustManagers());
        conduit.setTlsClientParameters(tlsParams);
        
		String response = client.sayHello("han");
		System.out.println(response);
	}
	
	private static TrustManager[] getTrustManagers() throws IOException {
		try {
			String alg = TrustManagerFactory.getDefaultAlgorithm();
			TrustManagerFactory factory = TrustManagerFactory.getInstance(alg);
			InputStream fp = HelloWorldClient.class.getResourceAsStream(trustStore);
			KeyStore ks = KeyStore.getInstance("JKS");
			ks.load(fp, trustStorePass.toCharArray());
			fp.close();
			factory.init(ks);
			TrustManager[] tms = factory.getTrustManagers();
			return tms;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private static KeyManager[] getKeyManagers() throws IOException {
		try {
			String alg = KeyManagerFactory.getDefaultAlgorithm();
			KeyManagerFactory factory = KeyManagerFactory.getInstance(alg);
			InputStream fp = HelloWorldClient.class.getResourceAsStream(keyStore);
			KeyStore ks = KeyStore.getInstance("JKS");
			ks.load(fp, keyStorePass.toCharArray());
			fp.close();
			factory.init(ks, keyStorePass.toCharArray());
			KeyManager[] keyms = factory.getKeyManagers();
			return keyms;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		}
		return null;
	}
}

 

9.现在就可以运行client端测试鉴权功能了。
   
    本来想着认真解释一下代码,不过环境太吵,实在没法安静下来写,就算是抛砖引玉吧。

分享到:
评论
1 楼 itcyt 2011-12-26  
楼主,基于rest service 怎么加入安全验证?谢谢

相关推荐

    webService(基于cxf)的完整例子

    在这个基于CXF的Web服务完整例子中,我们将深入探讨CXF的核心概念、配置、以及如何创建和调用Web服务。 1. **CXF框架介绍**:CXF,全称为"Code first eXtended Framework",最初由XFire项目发展而来,后与Apache ...

    CXF webservice 验证码接口

    使用jdk1.6、cxf2.3和tomcat开发的一个关于验证码的webservice接口,主要实现对手机验证码的验证。

    cxf WebService jar包(1)

    cxf WebService jar包

    CXF webservice+mybatis

    将CXF和Mybatis整合,可以创建一个基于Web服务的数据访问层。以下是整合步骤: 1. **创建服务接口**:定义一个Java接口,包含CRUD操作。 2. **创建服务实现**:实现该接口,并使用Mybatis的SqlSession执行SQL操作...

    cxf webservice demo

    此"CXF Webservice Demo"是一个实例,展示了如何使用CXF来创建和消费Web服务。CXF允许开发者通过SOAP(简单对象访问协议)和RESTful(Representational State Transfer)接口进行通信,支持多种协议和绑定,如HTTP、...

    实战Web+Service+with+CXF webservice快速入门

    实战Web+Service+with+CXF webservice快速入门 webservice快速入门

    mybatis+spring+cxf Webservice框架

    4. **Web服务**:理解SOAP协议,包括WSDL(Web Services Description Language)和XSD(XML Schema Definition),以及如何通过CXF实现基于SOAP的Web服务是非常重要的。 5. **集成**:如何将MyBatis的持久层操作与...

    CXF webservice Demo

    【CXF Webservice Demo】是基于Apache CXF框架的一个示例项目,用于演示如何使用CXF来创建和消费Web服务。Apache CXF是一个开源的Java框架,它允许开发者构建和集成Web服务,支持多种Web服务标准,如SOAP、RESTful ...

    CXF webService 工具类

    - **Spring-WS**:侧重于基于WSDL的第一类公民,而CXF支持更广泛的Web服务标准和协议。 6. **最佳实践** - **模块化设计**:将服务接口和实现分离,提高代码可维护性。 - **利用注解**:使用JAX-WS或JAX-RS注解...

    基于CXF的webservice的发布及访问

    **基于CXF的Web服务发布及访问** 在Java开发中,Apache CXF是一个广泛使用的开源框架,用于构建和实现Web服务。本教程将详细介绍如何利用CXF发布基于SOAP 1.2的Web服务,以及如何进行客户端调用。首先,我们需要...

    maven项目 cxf webservice

    【标题】"maven项目 cxf webservice"指的是使用Maven构建的一个项目,该项目集成了Apache CXF框架来开发Web服务。Apache CXF是一个开源的Java框架,它允许开发者创建和消费各种Web服务,包括SOAP和RESTful服务。...

    C#动态调用CXF WEBSERVICE框架的共通类

    C#动态调用CXF WEBSERVICE框架共通类。

    CXF WebService 所需要的最少的jar包

    在这个主题中,我们将深入探讨CXF WebService所需的最小jar包集合,以及如何利用这些库来开发Web服务。 首先,CXF的核心功能依赖于一系列的jar包,这些jar包包含了处理不同协议、数据绑定、WS-Security等关键组件的...

    CXF WebService整合Spring代码(包含服务,客户端两个工程 和 文档)

    CXF WebService整合Spring代码(包含服务,客户端两个工程 和 文档) 需要视频的话,留邮箱

    使用cxf webservice时容易出现的异常

    使用cxf webservice时容易出现的异常

    基于cxf 的webService 接口开发及调用步骤文档

    ### 基于CXF的WebService接口开发及调用步骤详解 #### 一、概述 在当前企业级应用开发中,服务化与微服务架构逐渐成为主流趋势,而WebService作为一种跨语言、跨平台的服务交互方式,在众多场景下仍然发挥着重要...

    CXF webservice 示例工程(集成spring)

    本示例工程是基于CXF框架构建的一个Webservice应用,该应用集成了Spring框架,以实现更高效的服务管理和依赖注入。CXF是一个开源的Web服务框架,它允许开发者创建和部署SOAP和RESTful服务,同时也支持WS-*标准,如...

    基于CXF的webService本地数据交互----PC端与Android端(一)

    本文将深入探讨基于Apache CXF实现的Web Service在本地数据交互中的应用,尤其是如何在PC端与Android端之间进行通信。Apache CXF是一个开源框架,专门用于构建和消费Web服务,支持多种协议和标准,如SOAP、RESTful等...

    CXF webservice初学笔记

    【CXF Webservice初学笔记】 在IT行业中,Web服务是一种允许不同系统之间进行通信和交换数据的方法。Apache CXF是一个流行的开源框架,用于构建和部署Web服务。本笔记将探讨CXF Webservice的基础知识,包括其核心...

    基于CXF实现WebService开发.pdf

    根据提供的文件内容,以下知识点是关于基于Apache CXF实现WebService开发的详细说明: Apache CXF是一个开源服务框架,它使得创建和开发WebService变得简单。CXF提供了完整的WebService功能,包括对JAX-WS的支持...

Global site tag (gtag.js) - Google Analytics