读书人

Apache CXF实战之6 创建安全的Web Ser

发布时间: 2013-04-20 19:43:01 作者: rapoo

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

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

1. 首先是一个简单pojo

?

[java]?view plaincopyprint??
  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接口

?

?

[java]?view plaincopyprint??
  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实现类

?

?

[java]?view plaincopyprint??
  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来存放用户信息,真是应用中可以使用数据库或者其它方式获取用户和密码

?

?

[java]?view plaincopyprint??
  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,用来设置用户密码,在真实应用中可以根据此类和下面的测试类来修改逻辑设置用户名和密码。

?

?

[java]?view plaincopyprint??
  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列表中。

?

?

[java]?view plaincopyprint??
  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前端

热点推荐