博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CXF 入门:创建一个基于WS-Security标准的安全验证(CXF回调函数使用)(转)
阅读量:6932 次
发布时间:2019-06-27

本文共 6998 字,大约阅读时间需要 23 分钟。

注意:以下客户端调用代码中获取服务端ws实例,都是通过方式实现

 

直入正题!

以下是服务端配置

========================================================

一,web.xml配置,具体不在详述

contextConfigLocation
WEB-INF/ws-context.xml,WEB-INF/wssec.xml
org.springframework.web.context.ContextLoaderListener
CXFServlet
CXF Servlet
org.apache.cxf.transport.servlet.CXFServlet
0
CXFServlet
/services/*

 二,ws具体代码
简单的接口

 

import javax.jws.WebService;@WebService()public interface WebServiceSample {	String say(String name);}

 

 

接口具体实现类

 

public class WebServiceSampleImpl implements WebServiceSample {	public String say(String name) {		return "你好," + name;	}}

 

 

 

三,ws回调函数,必须实现javax.security.auth.callback.CallbackHandler

从cxf2.4.x后校验又cxf内部实现校验,所以不必自己校验password是否相同,但客户端必须设置,详情请参考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime  Changes片段

 

回调函数WsAuthHandler代码,校验客户端请求是否合法 ,合法就放行,否则拒绝执行任何操作

 

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.cxf.interceptor.Fault;import org.apache.ws.security.WSPasswordCallback;import org.apache.xmlbeans.impl.soap.SOAPException;public class WsAuthHandler implements CallbackHandler {	public void handle(Callback[] callbacks) throws IOException,			UnsupportedCallbackException {		for (int i = 0; i < callbacks.length; i++) {			WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];			String identifier = pc.getIdentifier();			int usage = pc.getUsage();			if (usage == WSPasswordCallback.USERNAME_TOKEN) {// 密钥方式USERNAME_TOKEN				// username token pwd...				// ▲这里的值必须和客户端设的值相同,从cxf2.4.x后校验方式改为cxf内部实现校验,不必自己比较password是否相同				// 请参考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime				// Changes片段				pc.setPassword("testPassword");// ▲【这里非常重要】▲				// ▲PS 如果和客户端不同将抛出org.apache.ws.security.WSSecurityException:				// The				// security token could not be authenticated or				// authorized异常,服务端会认为客户端为非法调用			} else if (usage == WSPasswordCallback.SIGNATURE) {// 密钥方式SIGNATURE				// set the password for client's keystore.keyPassword				// ▲这里的值必须和客户端设的值相同,从cxf2.4.x后校验方式改为cxf内部实现校验,不必自己比较password是否相同;				// 请参考:http://cxf.apache.org/docs/24-migration-guide.html的Runtime				// Changes片段				pc.setPassword("testPassword");// //▲【这里非常重要】▲				// ▲PS:如果和客户端不同将抛出org.apache.ws.security.WSSecurityException:The				// security token could not be authenticated or				// authorized异常,服务端会认为客户端为非法调用			}			//不用做其他操作		}	}}

 

 

四,CXF配置ws-context.xml:

 

 

 

CXF配置wssec.xml(可选),用于配置输出校验的具体信息

 

 

服务端代码及配置到此结束!!!

 

=========================================================

=========================================================

以下是客户端配置,主要是回调函数,在客户端调用服务端前被调用,负责安全信息的设置

----------------------------------------------------------------------------------------

 

 

一,先实现回调函数WsClinetAuthHandler,同样必须实现javax.security.auth.callback.CallbackHandler

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 WsClinetAuthHandler implements CallbackHandler {	public void handle(Callback[] callbacks) throws IOException,			UnsupportedCallbackException {		for (int i = 0; i < callbacks.length; i++) {			WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];			System.out.println("identifier: " + pc.getIdentifier());			// 这里必须设置密码,否则会抛出:java.lang.IllegalArgumentException: pwd == null			// but a password is needed			pc.setPassword("testPassword");// ▲【这里必须设置密码】▲		}	}}
 

二,客户端调用代码:

 

import java.util.ArrayList;import java.util.HashMap;import java.util.Map;import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;import org.apache.ws.security.WSConstants;import org.apache.ws.security.handler.WSHandlerConstants;import test.saa.client.WebServiceSample;import test.saa.handler.WsClinetAuthHandler;public class TestClient {	public static void main(String[] args) {		// 以下和服务端配置类似,不对,应该说服务端和这里的安全验证配置一致		Map
outProps = new HashMap
(); outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); outProps.put(WSHandlerConstants.USER, "admin"); outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); // 指定在调用远程ws之前触发的回调函数WsClinetAuthHandler,其实类似于一个拦截器 outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, WsClinetAuthHandler.class.getName()); ArrayList list = new ArrayList(); // 添加cxf安全验证拦截器,必须 list.add(new SAAJOutInterceptor()); list.add(new WSS4JOutInterceptor(outProps)); JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); // WebServiceSample服务端接口实现类,这里并不是直接把服务端的类copy过来,具体请参考http://learning.iteye.com/blog/1333223 factory.setServiceClass(WebServiceSample.class); // 设置ws访问地址 factory.setAddress("http://localhost:8080/cxf-wssec/services/WebServiceSample"); //注入拦截器,用于加密安全验证信息 factory.getOutInterceptors().addAll(list); WebServiceSample service = (WebServiceSample) factory.create(); String response = service.say("2012"); System.out.println(response); }}

 客户端到此结束!!!!

========================================================================

#######################################################################

 

PS:客户端的另一种调用方式,主要通过配置文件,不过需要spring bean的配置文件(第一种就不用牵扯到spring的配置,比较通用吧!)

 

一,回调函数WsClinetAuthHandler不变,和上面一样
二,client-beans.xml安全验证配置文件,具体信息看注释,如下:

 

 
三,具体调用服务端代码:

 

import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import test.saa.client.WebServiceSample;public final class Client {	public static void main(String args[]) throws Exception {	//加载配置		ApplicationContext context = new ClassPathXmlApplicationContext(				new String[] { "test/saa/client-beans.xml" });        //获取ws实例		WebServiceSample client = (WebServiceSample) context.getBean("client");		String response = client.say("2012");		System.out.println("Response: " + response);	}}

 
到此客户端第二种实现方式结束
GOOD LUCKY!!!
如有不明,请指教!!!

 

来源:http://www.blogjava.net/zljpp/archive/2012/04/15/374371.html

 

转载于:https://www.cnblogs.com/edison2012/p/6292154.html

你可能感兴趣的文章
修改PHP上传文件大小限制的方法
查看>>
OLAP与OLTP介绍
查看>>
Mac 安装md5sum等
查看>>
memcached client --ref
查看>>
MyBatis魔法堂:ResultMap详解
查看>>
《基于Windows 7特性的程序开发系列》视频分享
查看>>
SilverLight.3-Validation:二、银光验证。TheLabel、TheDescriptionViewer和TheValidationSummary...
查看>>
二叉树的非递归遍历(递归和非递归)
查看>>
第 13 章 编码风格
查看>>
WPF 浏览PDF 文件
查看>>
代码的印象派:写点好代码吧
查看>>
javascript全局观
查看>>
1.4. Rosegarden
查看>>
查看oralce的版本及安装了哪些选项
查看>>
uC/OS-II源码分析(四)
查看>>
图像编程魔法门(By C#) 目录
查看>>
cross join
查看>>
jsoup 多个 class Selector 怎么写?
查看>>
让你上瘾的网易云音乐推荐算法,用Word2vec就可以实现
查看>>
[LeetCode] Mini Parser 迷你解析器
查看>>