Loading

cxf+ws-security+加密实现方式

网上看的CXF+ws-secutiry大多是通过配置相关的xml文件来进行服务端部署,这儿给出不一样的做法。 

web service接口及实现

package com.cxf.libraryServer;
import javax.jws.WebMethod;

@javax.jws.WebService
public interface WebService {
    @WebMethod
    String serviceTest();
}



package com.cxf.libraryServer;

@javax.jws.WebService(
        name = "WebService",
        targetNamespace = ""
)
public class WebServiceImpl implements WebService {
    @Override
    public String serviceTest() {
        return "success";
    }
}

 

服务端

 1 package com.cxf.libraryServer.Server;
 2 
 3 import com.cxf.libraryServer.WebService;
 4 import com.cxf.libraryServer.WebServiceImpl;
 5 import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
 6 import org.apache.cxf.interceptor.LoggingInInterceptor;
 7 import org.apache.cxf.interceptor.LoggingOutInterceptor;
 8 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 9 import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
10 
11 import java.util.HashMap;
12 import java.util.Map;
13 
14 public class WebServicePublish {
15     public static void main(String[] args) {
16         String address = "wsdl地址";
17         //采用JDK方式进行发布
18 //        Endpoint.publish(address, new WebServiceImpl());
1920 
21         //采用JaxWsServerFactoryBean方式
22         JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
23         //服务发布地址
24         jaxWsServerFactoryBean.setAddress(address);
25         //提供服务类的类型
26         jaxWsServerFactoryBean.setServiceClass(WebService.class);
27         //提供服务的实例
28         jaxWsServerFactoryBean.setServiceBean(new WebServiceImpl());
29         //
30         Map<String, Object> props = new HashMap<String, Object>();
31         props.put("action", "UsernameToken");
32         props.put("passwordType", "PasswordDigest");
33         props.put("user", "cxfname");
34         props.put("passwordCallbackClass", "com.cxf.libraryServer.Server.ServerPasswordCallback");
35         WSS4JInInterceptor wss4jIn = new org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor(props);
36         //
37         jaxWsServerFactoryBean.getInInterceptors().add(wss4jIn);
38         jaxWsServerFactoryBean.getInInterceptors().add((new SAAJInInterceptor()));
39         jaxWsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
40         jaxWsServerFactoryBean.getInInterceptors().add(new LoggingOutInterceptor());
41         //发布服务
42         jaxWsServerFactoryBean.create();
43         System.out.println("图书馆接口发布成功");
44     }
45 }

服务端回调函数:用于验证密码

package com.libraryServer.Server;

import org.apache.wss4j.common.ext.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class ServerPasswordCallback implements CallbackHandler {
    public void handle(Callback[] args) throws IOException,UnsupportedCallbackException {
        for (int i = 0; i < args.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback) args[i];
            String identifier = pc.getIdentifier();
            if ("cxfname".equals(identifier)) {
                pc.setPassword("admin");
            }
        }
    }
}

客户端

package com.cxf.libraryServer.ClientTest;

import com.cxf.libraryServer.WebService;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;

import java.util.HashMap;
import java.util.Map;

public class Client {
    public WebService UserAccess() {
        try {
            String REMOTEDATA_CXF_NAME = "cxfname";
            String REMOTEDATA_CXF_WSDL = "wsdl地址";
            JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();
            jwpFactory.setAddress(REMOTEDATA_CXF_WSDL);
            jwpFactory.setServiceClass(WebService.class);
            //
            Map<String, Object> outProps = new HashMap<String, Object>();
            outProps.put("action", "UsernameToken");
            outProps.put("user", REMOTEDATA_CXF_NAME);
            outProps.put("passwordType", "PasswordDigest");
            outProps.put("passwordCallbackClass", "com.cxf.libraryServer.ClientTest.WSAuthHandler");
            WSS4JOutInterceptor wss4jOut = new org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor(outProps);
            //
            jwpFactory.getOutInterceptors().add(wss4jOut);
            jwpFactory.getOutInterceptors().add(new SAAJOutInterceptor());
            jwpFactory.getOutInterceptors().add(new LoggingOutInterceptor());
            jwpFactory.getOutInterceptors().add(new LoggingInInterceptor());
            return (WebService) jwpFactory.create();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

客户端回调函数:用于发送密码

package com.cxf.libraryServer.ClientTest;

import org.apache.wss4j.common.ext.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class WSAuthHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
            // 这里必须设置密码,否则会抛出:java.lang.IllegalArgumentException: pwd == null
            // but a password is needed
            pc.setPassword("admin");
        }
    }
}

测试结果:在test层中测试

@Test
    public void myCXF_WebserviceTest(){
        Client client = new Client();
        WebService webService = client.UserAccess();
        System.out.println(webService.serviceTest());
    }

成功打印出:success

 

 参考资料

webservice cxf学习,重点是加密

Java code examples for org.apache.cxf.ws.ssecurity.wss4j.Wss4JOutInterceptor

浅谈springmvc整合CXF+ws-security实现wbservice安全验证

(ps:服务端发布是直接写main来测试,在项目中可以直接写个servlet来进行启动cxf服务,详细操作可以见:Java web项目启动时,自动执行代码的三种方式)

posted @ 2019-02-24 16:17  yoyuLiu  阅读(1401)  评论(0编辑  收藏  举报