重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
Apache CXF中如何创建安全的Web Service,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
公司主营业务:成都做网站、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联推出凤城免费做网站回馈大家。
我们在使用Web Service的过程中,很多情况是需要对web service请求做认证的,对于运行在web容器里的应用程序来说,可能会比较简单一些,通常可以通过filter来做一些处理,但是其实CXF本身也提供了对web service认证的方式。下面来看一下如何实现。
1. 首先是一个简单pojo
package com.googlecode.garbagecan.cxfstudy.security; public class User { private String id; private String name; private String password; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
2. Web Service接口
package com.googlecode.garbagecan.cxfstudy.security; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebResult; import javax.jws.WebService; @WebService public interface UserService { @WebMethod @WebResult Listlist(); }
3. Web Service实现类
package com.googlecode.garbagecan.cxfstudy.security; import java.util.ArrayList; import java.util.List; public class UserServiceImpl implements UserService { public Listlist() { List users = new ArrayList (); for (int i = 0; i < 10; i++) { User user = new User(); user.setId("" + i); user.setName("user_" + i); user.setPassword("password_" + i); users.add(user); } return users; } }
4. Server端Handler,其中使用了一个Map来存放用户信息,真是应用中可以使用数据库或者其它方式获取用户和密码
package com.googlecode.garbagecan.cxfstudy.security; import java.io.IOException; import java.util.HashMap; import java.util.Map; 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 ServerUsernamePasswordHandler implements CallbackHandler { // key is username, value is password private Mapusers; public ServerUsernamePasswordHandler() { users = new HashMap (); users.put("admin", "admin"); } public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback callback = (WSPasswordCallback) callbacks[0]; String id = callback.getIdentifier(); if (users.containsKey(id)) { if (!callback.getPassword().equals(users.get(id))) { throw new SecurityException("Incorrect password."); } } else { throw new SecurityException("Invalid user."); } } }
5. Client端Handler,用来设置用户密码,在真实应用中可以根据此类和下面的测试类来修改逻辑设置用户名和密码。
package com.googlecode.garbagecan.cxfstudy.security; 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 ClientUsernamePasswordHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback callback = (WSPasswordCallback) callbacks[0]; int usage = callback.getUsage(); System.out.println("identifier: " + callback.getIdentifier()); System.out.println("usage: " + callback.getUsage()); if (usage == WSPasswordCallback.USERNAME_TOKEN) { callback.setPassword("admin"); } } }
6. 单元测试类,注意在Server端添加了WSS4JInInterceptor到Interceptor列表中,在Client添加了WSS4JOutInterceptor到Interceptor列表中。
package com.googlecode.garbagecan.cxfstudy.security; import java.net.SocketTimeoutException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.ws.WebServiceException; import junit.framework.Assert; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.WSConstants; import org.apache.ws.security.handler.WSHandlerConstants; import org.junit.BeforeClass; import org.junit.Test; public class UserServiceTest { private static final String address = "http://localhost:9000/ws/security/userService"; @BeforeClass public static void setUpBeforeClass() throws Exception { JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.getInInterceptors().add(new LoggingInInterceptor()); factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); Mapprops = new HashMap (); props.put("action", "UsernameToken"); props.put("passwordType", "PasswordText"); props.put("passwordCallbackClass", ServerUsernamePasswordHandler.class.getName()); WSS4JInInterceptor wss4JInInterceptor = new WSS4JInInterceptor(props); factoryBean.getInInterceptors().add(wss4JInInterceptor); factoryBean.setServiceClass(UserServiceImpl.class); factoryBean.setAddress(address); factoryBean.create(); } @Test public void testList() { JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean(); factoryBean.setAddress(address); factoryBean.setServiceClass(UserService.class); Object obj = factoryBean.create(); Client client = ClientProxy.getClient(obj); Endpoint endpoint = client.getEndpoint(); Map props = new HashMap (); props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); props.put(WSHandlerConstants.USER, "admin"); props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); props.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientUsernamePasswordHandler.class.getName()); WSS4JOutInterceptor wss4JOutInterceptor = new WSS4JOutInterceptor(props); endpoint.getOutInterceptors().add(wss4JOutInterceptor); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); policy.setConnectionTimeout(5 * 1000); policy.setReceiveTimeout(5 * 1000); conduit.setClient(policy); UserService service = (UserService) obj; try { List users = service.list(); Assert.assertNotNull(users); Assert.assertEquals(10, users.size()); } catch(Exception e) { if (e instanceof WebServiceException && e.getCause() instanceof SocketTimeoutException) { System.err.println("This is timeout exception."); } else { e.printStackTrace(); } } } }
***运行上面的测试类来测试结果,也可以修改测试方法中的密码,看看错误结果,这里就不在写错误密码的测试用例了。
看完上述内容,你们掌握Apache CXF中如何创建安全的Web Service的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!