文档章节

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

DavidBao
 DavidBao
发布于 2015/05/31 21:45
字数 808
阅读 25
收藏 1

本文链接:http://blog.csdn.net/kongxx/article/details/7534035

Apache CXF实战之一 Hello World Web Service

Apache CXF实战之二 集成Sping与Web容器

Apache CXF实战之三 传输Java对象

Apache CXF实战之四 构建RESTful Web Service

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 List<User> list();

}
3. Web Service实现类

package com.googlecode.garbagecan.cxfstudy.security;

import java.util.ArrayList;
import java.util.List;

public class UserServiceImpl implements UserService {

    public List<User> list() {
        List<User> users = new ArrayList<User>();
        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 Map<String, String> users;

    public ServerUsernamePasswordHandler() {
        users = new HashMap<String, String>();
        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());

        Map<String, Object> props = new HashMap<String, Object>();
        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<String,Object> props = new HashMap<String,Object>();
        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<User> 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();
            }
        }
    }

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



本文转载自:http://blog.csdn.net/kongxx/article/details/7534035

DavidBao
粉丝 113
博文 213
码字总数 126729
作品 0
昌平
私信 提问
Apache CXF 3.1.15 发布,开源的 Service 框架

Apache CXF 3.1.15 发布了。Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面向服务架构(SOA)业务组件与技术的灵活复用。 更新内容: Bu...

淡漠悠然
2018/03/14
854
1
Apache CXF 2.4.0 发布

Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面 向服务架构(SOA)业务组件与技术的灵活复用。在CXF中,Service使用WSDL标准定义并能够使...

红薯
2011/04/19
2.6K
0
Apache CXF 3.0.16 发布,开源的 Service 框架

Apache CXF 3.0.16 发布了。Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面 向服务架构(SOA)业务组件与技术的灵活复用。 主要更新内容...

达尔文
2017/11/30
903
0
apache CXF wsdl2java工具的使用

最近,由于要用到某公司提供的webservice实现的api接口,想到了用cxf的wsdl2java工具来生成客户端程序。(自己写是比较麻烦且费时,so偷懒一下、、) 使用步骤如下: 一、下载apache cxf的包...

Yao淡定
2014/02/21
30K
0
Apache CXF 3.0.13 和 3.1.11 发布

Apache CXF 3.0.13 和 3.1.11 发布了,暂未发现具体更新内容。 点此查看 Apache CXF 3.0.13 和 3.1.11 的提交记录。 下载地址 和 发布主页 Apache CXF是一个开源的Service框架,它实现了JCP...

淡漠悠然
2017/04/06
944
3

没有更多内容

加载失败,请刷新页面

加载更多

springboot 403 问题

添加WebAppConfigurer 配置 @Configuration@EnableAutoConfigurationpublic class WebAppConfigurer extends WebMvcConfigurerAdapter { public WebAppConfigurer() { } ......

布袋和尚_爱吃鱼
10分钟前
2
0
Python自动更换壁纸爬虫与tkinter结合

直接上代码 import ctypesimport timeimport requestsimport osfrom threading import Threadfrom tkinter import Tk, Label, Button,Entry,StringVar,messagebox# '放到AppData\Roami......

物种起源-达尔文
10分钟前
1
0
Postgresql Study 笔记

Postgresql 安装 Windows, MAC Install Postgresql 下载地址: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads Linux Install sudo apt-get update sudo apt-get in......

slagga
12分钟前
2
0
layer.open 打开新页面传参问题

如图所示,点击出售,把A页面的数据传到弹框上面,因为弹框比较复杂,所以使用引入一个新页面。 A.html a.js B.html b.js 1、第一种方案 sellInte: function (){ var obj = document.g...

木九天
15分钟前
2
0
沙龙报名 | 区块链数据服务技术应用实践

京东云是国内首家提供区块链数据在线分析服务产品的公司,也是行业内首家对区块链数据服务进行开源的公司。 本次沙龙是京东云BDS开源后,首次在深圳举办线下沙龙,我们将邀请京东云BDS团队核...

京东云技术新知
16分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部