`

Apache CXF实战之六 创建安全的Web Service

 
阅读更多

我们在使用Web Service的过程中,很多情况是需要对web service请求做认证的,对于运行在web容器里的应用程序来说,可能会比较简单一些,通常可以通过filter来做一些处理,但是其实CXF本身也提供了对web service认证的方式。下面来看一下如何实现

1. 首先是一个简单pojo

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. public class User {  
  4.     private String id;  
  5.     private String name;  
  6.     private String password;  
  7.     public String getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(String id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public String getPassword() {  
  20.         return password;  
  21.     }  
  22.     public void setPassword(String password) {  
  23.         this.password = password;  
  24.     }  
  25. }  

2. Web Service接口

 

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.jws.WebMethod;  
  6. import javax.jws.WebResult;  
  7. import javax.jws.WebService;  
  8.   
  9. @WebService  
  10. public interface UserService {  
  11.     @WebMethod  
  12.     @WebResult List<User> list();  
  13.   
  14. }  

3. Web Service实现类

 

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class UserServiceImpl implements UserService {  
  7.   
  8.     public List<User> list() {  
  9.         List<User> users = new ArrayList<User>();  
  10.         for (int i = 0; i < 10; i++) {  
  11.             User user = new User();  
  12.             user.setId("" + i);  
  13.             user.setName("user_" + i);  
  14.             user.setPassword("password_" + i);  
  15.             users.add(user);  
  16.         }  
  17.         return users;  
  18.     }  
  19.   
  20. }  

4. Server端Handler,其中使用了一个Map来存放用户信息,真是应用中可以使用数据库或者其它方式获取用户和密码

 

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import javax.security.auth.callback.Callback;  
  8. import javax.security.auth.callback.CallbackHandler;  
  9. import javax.security.auth.callback.UnsupportedCallbackException;  
  10.   
  11. import org.apache.ws.security.WSPasswordCallback;  
  12.   
  13. public class ServerUsernamePasswordHandler implements CallbackHandler {  
  14.   
  15.     // key is username, value is password  
  16.     private Map<String, String> users;  
  17.   
  18.     public ServerUsernamePasswordHandler() {  
  19.         users = new HashMap<String, String>();  
  20.         users.put("admin""admin");  
  21.     }  
  22.   
  23.     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {  
  24.         WSPasswordCallback callback = (WSPasswordCallback) callbacks[0];  
  25.         String id = callback.getIdentifier();  
  26.         if (users.containsKey(id)) {  
  27.             if (!callback.getPassword().equals(users.get(id))) {  
  28.                 throw new SecurityException("Incorrect password.");  
  29.             }  
  30.         } else {  
  31.             throw new SecurityException("Invalid user.");  
  32.         }  
  33.     }  
  34. }  

5. Client端Handler,用来设置用户密码,在真实应用中可以根据此类和下面的测试类来修改逻辑设置用户名和密码。

 

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.security.auth.callback.Callback;  
  6. import javax.security.auth.callback.CallbackHandler;  
  7. import javax.security.auth.callback.UnsupportedCallbackException;  
  8.   
  9. import org.apache.ws.security.WSPasswordCallback;  
  10.   
  11. public class ClientUsernamePasswordHandler implements CallbackHandler {  
  12.     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {  
  13.         WSPasswordCallback callback = (WSPasswordCallback) callbacks[0];  
  14.         int usage = callback.getUsage();  
  15.         System.out.println("identifier: " + callback.getIdentifier());  
  16.         System.out.println("usage: " + callback.getUsage());  
  17.         if (usage == WSPasswordCallback.USERNAME_TOKEN) {  
  18.             callback.setPassword("admin");  
  19.         }  
  20.     }  
  21. }  

6. 单元测试类,注意在Server端添加了WSS4JInInterceptor到Interceptor列表中,在Client添加了WSS4JOutInterceptor到Interceptor列表中。

 

 

  1. package com.googlecode.garbagecan.cxfstudy.security;  
  2.   
  3. import java.net.SocketTimeoutException;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import javax.xml.ws.WebServiceException;  
  9.   
  10. import junit.framework.Assert;  
  11.   
  12. import org.apache.cxf.endpoint.Client;  
  13. import org.apache.cxf.endpoint.Endpoint;  
  14. import org.apache.cxf.frontend.ClientProxy;  
  15. import org.apache.cxf.interceptor.LoggingInInterceptor;  
  16. import org.apache.cxf.interceptor.LoggingOutInterceptor;  
  17. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  18. import org.apache.cxf.jaxws.JaxWsServerFactoryBean;  
  19. import org.apache.cxf.transport.http.HTTPConduit;  
  20. import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;  
  21. import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;  
  22. import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;  
  23. import org.apache.ws.security.WSConstants;  
  24. import org.apache.ws.security.handler.WSHandlerConstants;  
  25. import org.junit.BeforeClass;  
  26. import org.junit.Test;  
  27.   
  28. public class UserServiceTest {  
  29.   
  30.     private static final String address = "http://localhost:9000/ws/security/userService";  
  31.       
  32.     @BeforeClass  
  33.     public static void setUpBeforeClass() throws Exception {  
  34.         JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();  
  35.         factoryBean.getInInterceptors().add(new LoggingInInterceptor());  
  36.         factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());  
  37.   
  38.         Map<String, Object> props = new HashMap<String, Object>();  
  39.         props.put("action""UsernameToken");  
  40.         props.put("passwordType""PasswordText");  
  41.         props.put("passwordCallbackClass", ServerUsernamePasswordHandler.class.getName());  
  42.         WSS4JInInterceptor wss4JInInterceptor = new WSS4JInInterceptor(props);  
  43.         factoryBean.getInInterceptors().add(wss4JInInterceptor);  
  44.           
  45.         factoryBean.setServiceClass(UserServiceImpl.class);  
  46.         factoryBean.setAddress(address);  
  47.         factoryBean.create();  
  48.     }  
  49.   
  50.     @Test  
  51.     public void testList() {  
  52.         JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
  53.         factoryBean.setAddress(address);  
  54.         factoryBean.setServiceClass(UserService.class);  
  55.         Object obj = factoryBean.create();  
  56.           
  57.         Client client = ClientProxy.getClient(obj);  
  58.         Endpoint endpoint = client.getEndpoint();  
  59.           
  60.         Map<String,Object> props = new HashMap<String,Object>();  
  61.         props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);  
  62.         props.put(WSHandlerConstants.USER, "admin");  
  63.         props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);  
  64.         props.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientUsernamePasswordHandler.class.getName());  
  65.         WSS4JOutInterceptor wss4JOutInterceptor = new WSS4JOutInterceptor(props);  
  66.         endpoint.getOutInterceptors().add(wss4JOutInterceptor);  
  67.           
  68.         HTTPConduit conduit = (HTTPConduit) client.getConduit();  
  69.         HTTPClientPolicy policy = new HTTPClientPolicy();  
  70.         policy.setConnectionTimeout(5 * 1000);  
  71.         policy.setReceiveTimeout(5 * 1000);  
  72.         conduit.setClient(policy);  
  73.           
  74.         UserService service = (UserService) obj;  
  75.         try {  
  76.             List<User> users = service.list();  
  77.             Assert.assertNotNull(users);  
  78.             Assert.assertEquals(10, users.size());  
  79.         } catch(Exception e) {  
  80.             if (e instanceof WebServiceException   
  81.                     && e.getCause() instanceof SocketTimeoutException) {  
  82.                 System.err.println("This is timeout exception.");  
  83.             } else {  
  84.                 e.printStackTrace();  
  85.             }  
  86.         }  
  87.     }  
  88.   
  89. }  

最后运行上面的测试类来测试结果,也可以修改测试方法中的密码,看看错误结果,这里就不在写错误密码的测试用例了,因为我是一懒人。

分享到:
评论

相关推荐

    实战Web Service —— 使用Apache CXF开发Web服务的教程

    **实战Web Service与Apache CXF开发** Web服务是一种在互联网上进行通信的标准协议,它允许应用程序之间进行数据交换。Apache CXF是一个开源框架,用于构建和部署Web服务,支持多种Web服务标准,如SOAP、RESTful ...

    Apache_cxf_学习笔记

    Apache CXF 是一个开源的Java框架,主要用于构建和开发服务导向架构(Service-Oriented Architecture, SOA)和Web服务。本学习笔记旨在提供对Apache CXF的基本理解、功能特性和实际操作指导。 **1. CXF 简介** 1.1...

    Developing Web Services with Apache CXF and Axis2_3rd Edition

    本书《开发Web服务:使用Apache CXF与Axis2》是针对希望学习如何使用Java创建Web服务的专业人士所编写的实用教程。作者Kent Kai Ok Tong以简明扼要的方式介绍了一系列复杂的Web服务标准和技术,并通过实际示例帮助...

    CXF 框架实战代码---服务器端WebServices接口

    在本文中,我们将深入探讨Apache CXF框架在创建服务器端Web服务接口中的应用。Apache CXF是一个开源的Java框架,它允许开发者构建和部署SOAP(简单对象访问协议)和RESTful(表述性状态转移)Web服务。CXF以其灵活性...

    实战Web+Service+with+CXF

    实战Web+Service+with+CXF

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

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

    spring2.5+ibatis3+web service cxf 例子MyEclipse工程

    标题中的“spring2.5+ibatis3+web service cxf”揭示了这是一个关于整合Spring 2.5、iBATIS 3和Apache CXF Web服务的示例项目。这个项目是在MyEclipse环境中构建的,它是一个强大的Java集成开发环境,特别适合企业级...

    Java实训教程 Java软件开发实战 Java开发框架介绍 webservices-cxf 共30页.pptx

    通过上述内容的学习,我们可以了解到Web Service技术的基本概念及其在Java环境中的应用,特别是Apache CXF框架如何帮助开发者快速搭建Web Service服务端。这对于从事Java软件开发的工程师来说是非常实用的知识点。...

    cfx web service

    Apache CXF 2.6.2是该框架的一个版本,它提供了丰富的功能和工具,便于开发者创建、部署和管理Web服务。 **一、Apache CXF概述** Apache CXF是一个高度可扩展的框架,支持多种Web服务标准,如SOAP、WSDL、WS-I基本...

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

    在本篇博文中,我们将深入探讨如何利用Apache CXF库创建和实现基于Web Service的本地数据交互,特别是在PC端的应用。Apache CXF是一个开源框架,它允许开发者构建和部署服务,支持多种Web服务规范,如SOAP、RESTful...

    CXF 框架实战代码---服务器端发布WebServices接口

    本篇将深入探讨如何利用CXF框架在服务器端发布WebServices接口,并通过具体的实战代码来阐述这一过程。 一、CXF框架介绍 CXF全称是CXF-CXF Fuses XFire和 Celtix,是一个Java EE平台上的Web服务框架。它支持多种...

    CXF 框架实战代码--服务器端CXF接口发布与调用

    在本实战教程中,我们将深入探讨如何在服务器端使用CXF来发布和调用Web服务接口。 ### 1. CXF框架基础 CXF的核心在于其强大的服务引擎,它允许开发者以Java编程模型来定义服务接口,并自动生成相应的服务实现和...

    CXF结合Spring开发WebServices示例工程

    在本文中,我们将深入探讨如何使用Apache CXF与Spring框架集成来开发Web Services。CXF是一个流行的开源项目,它提供了一种灵活的方式来实现和消费Web Services。Spring则是一个全面的企业级应用开发框架,两者结合...

    MyEclipse[实战开发讲解入门..XFire.Web.Service.入门

    5. **XFire Web Service入门**:XFire(现已被Apache CXF合并)是Java的Web Service框架,用于创建和消费Web服务。关键文档“MyEclipse[1].6.实战开发讲解视频入门.8.XFire.Web.Service.入门.doc”会指导开发者如何...

    xfire_1.147_zol.zip 加 Web_Service学习手册(Xfire)-christian.pdf

    6. **实战演练**:通过阅读《Web Service学习手册(Xfire)-christian.pdf》和压缩包中的示例代码,可以了解如何使用XFire或CXF创建服务、编写客户端代码,以及如何测试和调试Web Service。 总之,Web Service是现代...

    Web-Service学习手册(Xfire).docx

    1.3.3 CXF:CXF是另一个流行的开源Web Service框架,它结合了Xfire和Apache SOAP项目的优点,支持多种Web Service规范,并且可以与Spring框架无缝集成。 1.3.4 主流 Web Service 的比较 Axis适合初学者,因为它的...

    cxf html.rar

    5. **RESTful Web服务创建**:压缩包中的文件如“RESTful Web Service(二)使用eclipse创建restful webservice 工程”说明了如何使用Eclipse IDE创建RESTful Web服务的步骤,这是开发过程中非常实用的一个教程。...

    cxf+spring webservice server demo

    【标题】"cxf+spring webservice server demo"是一个基于Apache CXF和Spring框架构建的Web服务服务器端示例项目。这个项目展示了如何将CXF与Spring集成,以创建、部署和运行一个高效的Web服务。 【描述】指出,由于...

Global site tag (gtag.js) - Google Analytics