CXF—六天系列—第四天—HelloWorld!-通过servlet发布webservice . .

前3节中介绍了如何发布一个webservice和客户端如何调用,一切貌似都正常,但存在着安全隐患-这样导致任意的客户端都可以调用我们的webservice服务,接下来将介绍如何采用基于用户名和密码认证的方式来实现客户端调用

1.服务器端配置

a.在发布service的时候为该service添加一个WSS4JInInterceptor 拦截器

表示我们的service需要用户提供用户名和密码认证后才能调用

package com.crazycoder2010.webservice.cxf.server;  
  
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;

import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.service.invoker.BeanInvoker;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;  
  
<SPAN><SPAN class=keyword></SPAN></SPAN>import com.crazycoder2010.webservice.cxf.server.HelloWorldServiceImpl;  
  
public class WebServiceServlet extends CXFNonSpringServlet {  
    private static final long serialVersionUID = -5314312869027558456L;  
  
    @Override  
    protected void loadBus(ServletConfig servletConfig) {  
        super.loadBus(servletConfig);  
        System.out.println("#####################");  
        ServerFactoryBean svrFactory = new ServerFactoryBean();
        svrFactory.setServiceClass(HelloWorldService.class);
        svrFactory.setAddress("/passportService");
        svrFactory.setInvoker(new BeanInvoker(new HelloWorldServiceImp()));
        Server server = svrFactory.create();
        Endpoint cxfEndpoint = server.getEndpoint();
        Map<String, Object> inProps = new HashMap<String, Object>();
        inProps.put(WSHandlerConstants.ACTION,
                WSHandlerConstants.USERNAME_TOKEN);
        inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
        inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
                ServerPasswordHandler.class.getName());
        cxfEndpoint.getInInterceptors().add(new WSS4JInInterceptor(inProps));
    }  
}


b.处理用户名和密码的逻辑

添加一个ServerPasswordHandler类,该类实现CallbackHandler接口,user='kevin',password='111111'为该service的访问用户名密码

public class ServerPasswordHandler implements CallbackHandler{
	private String user = "kevin";
	private String password = "111111";
	@Override
	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
		if(user.equals(pc.getIdentifier())){
			pc.setPassword(password);
		}
	}
}


2.客户端配置

a.配置WSS4JOutInterceptor拦截器,表示发出请求的时候将以提供的用户名和密码信息提交到服务器端认证

public class WebServiceFactory {
	public static PassportService getHelloWorldService(){
	Map<String,Object> outProps = new HashMap<String,Object>();
	outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
	outProps.put(WSHandlerConstants.USER, "kevin");//这个用户即服务器端配置的用户名
	outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
	outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordHandler.class.getName());//这个类用来获取客户端认证用户名密码信息
	JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();  
        bean.getInInterceptors().add(new LoggingInInterceptor());  
        bean.getInFaultInterceptors().add(new LoggingOutInterceptor()); 
        bean.setServiceClass(PassportService.class);
        bean.setAddress("http://localhost:8080/CXF-Server/webservice/helloWorldService"); 
        HelloWorldService helloWorldService = (HelloWorldService)bean.create();
        ClientProxy clientProxy = (ClientProxy)Proxy.getInvocationHandler(passportService);
        Client client = clientProxy.getClient();
        client.getOutInterceptors().add(new WSS4JOutInterceptor(outProps));//配置拦截器
        return helloWorldService;
	}
}


b.配置客户端认证信息类

public class ClientPasswordHandler implements CallbackHandler{
	@Override
	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
	WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        pc.setPassword("kevin");//这个地方的用户名和密码与服务器端保持一致	
        pc.setIdentifier("111111");
	}
}


c.客户端调用

public class DemoClient {
	public static void main(String[] args) {
<PRE class=java name="code">                HelloWorldService helloWorldService = WebServiceFactory.getHelloWorldService();
		helloWorldService.sayHello("John");
	}
}</PRE>
<PRE></PRE>
<P></P>
<PRE></PRE>
小结:
<P></P>
<P>这种方式利用服务器端与客户端共享同一用户名密码的方式实现了webservice的安全访问,流程图如下</P>
<P><IMG alt="" src="http://hi.csdn.net/attachment/201108/17/0_13135751629tGv.gif"></P>
<P>参考资料:<A href="http://cxf.apache.org/docs/ws-security.html" target=_blank>http://cxf.apache.org/docs/ws-security.html</A><BR>
</P>
<P><BR>
</P>
<BR>


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值