CXF 服务端校验soapHeader,客户端添加soapHeader 记录

  整体需求是这样的,作为服务端,我的接口需要有一个安全验证,因此做了一个拦截器来验证soapHeader。作为客户端,需要往soapHeader中添加双方规定的参数。搞了一天多,在网上看了很多方法,最终还是搞定了。不得不说,现在网上的抄袭现象太严重了,有的博客甚至把别人分享的东西搬过来,连一个字都不带改的……

服务端拦截器验证soapHeader

  服务端主要是spring,接口是通过CXF发布的,贴一下spring配置文件代码

<bean id="SendDataService" class="com.ipt.webservice.send.impl.SendDataServiceImpl" />
	<jaxws:endpoint id="sendData" implementor="#SendDataService"
		address="/sendData" >
	<!-- 加入拦截器 -->
	<jaxws:inInterceptors>
		<bean class="com.ipt.filter.WebServiceInterceptor"></bean>
	</jaxws:inInterceptors>	
	</jaxws:endpoint>

  然后需要写一个拦截器 (WebServiceInterceptor),该类需要继承 AbstractPhaseInterceptor

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.ipt.util.CommonUtil;

public class WebServiceInterceptor extends
		AbstractPhaseInterceptor<SoapMessage> {

	public WebServiceInterceptor() {
		super(Phase.PRE_INVOKE);
	}

	public void handleMessage(SoapMessage soapMsg) throws Fault {

		List<Header> headers = soapMsg.getHeaders();// 根据soap消息获取头部
		if (headers == null || headers.size() == 0) {
			throw new Fault(new IllegalArgumentException("拒绝访问,原因:没有header!"));
		}
		for (Header header : headers) {
			Element ele = (Element) header.getObject();
			NodeList nodeList = ele.getElementsByTagName("entryStr");
			if (nodeList == null || nodeList.getLength() == 0) {
				throw new Fault(new IllegalArgumentException("拒绝访问,原因:通行信息为空!"));
			}
			String entryStr = nodeList.item(0).getTextContent();
			if (StringUtils.isNotBlank(entryStr)) {
				boolean entryFlag = CommonUtil.validRequestClient(entryStr);
				if (!entryFlag) {
					throw new Fault(new IllegalArgumentException(
							"拒绝访问,原因:通行信息验证未通过!"));
				}
			} else {
				throw new Fault(new IllegalArgumentException("拒绝访问,原因:通行信息为空!"));
			}
		}

	}

}

这样服务端的验证功能就完成了。

首先我们通过soapUI工具来验证一下接口

失败示例1:

CXF 服务端校验soapHeader,客户端添加soapHeader 记录

失败示例2:

CXF 服务端校验soapHeader,客户端添加soapHeader 记录

成功示例:

CXF 服务端校验soapHeader,客户端添加soapHeader 记录

服务器端的验证已经没有问题了,最重要的是要有soapHeader,并且header中的格式应为  <check><entryStr>value</entryStr></check>,接下来我们看客户端。

CXF客户端添加soapHeader

  我的客户端是通过 wsdl2java 工具生成的,其中有一个小插曲,我一开始下载了apache-cxf-3.3.2,但是一直报错(Unsupported major.minor version 52.0),应该是这个版本需要JDK1.7,但是我环境变量配的是jdk1.7,后来又下载了apache-cxf-3.1.15 就没问题了。下载完成后需要配置一下环境变量,然后就能生成代码了,然后新建一个java项目,把生成的代码拷贝到项目中。

CXF 服务端校验soapHeader,客户端添加soapHeader 记录

接下来需要写一个添加soapHeader的类,再调用服务端的方法之前先添加header

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
 * 添加soapHeader
 */
public class ClientCheckInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
	public static final String ENTRY_STR = "123456admin"; 
	public ClientCheckInterceptor() {
		super(Phase.PREPARE_SEND);
	}
	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		List<Header> headers = message.getHeaders();
		Document document = DOMUtils.createDocument();
		Element checkEle = document.createElement("check");
		Element entryStrEle = document.createElement("entryStr");
		entryStrEle.setTextContent(ENTRY_STR);
		checkEle.appendChild(entryStrEle);
		headers.add(new Header(new QName(""),checkEle));
	}

}

接下来写测试类 ServiceTest.java

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;

import com.ipt.webservice.send.SendDataService;
import com.ipt.webservice.send.impl.SendDataServiceImplService;

public class ServiceTest {
	
	public static void main(String[] args) {
		SendDataServiceImplService service = new SendDataServiceImplService();
		SendDataService port = service.getSendDataServiceImplPort();
		
                //添加soapHeader
		Client client = ClientProxy.getClient(port);
		client.getOutInterceptors().add(new ClientCheckInterceptor());
		//调用服务端发布的方法
		String task = port.queryCommittee();
		System.out.println(task);
		
	}
	
	
}

最后右键-run,测试一下是否能通过验证。控制台打印信息如下,访问成功

CXF 服务端校验soapHeader,客户端添加soapHeader 记录

 

客户端中我用到了两个jar包:cxf-2.4.3.jar 和 cxf-manifest.jar

  客户端代码(含客户端代码 + jar包 + apache-cxf-3.1.15)

 

 

上一篇:EodData wsdl java连接


下一篇:java – 字符串参数通常会在Web服务中自动转义吗?