webservice自定义拦截器,及客户端,soapui等

由于本人公司对webservice要增加安全性校验,需要接入权限验证,所以考虑用拦截这种方式,比较简单,也好扩展。内容如下:

1、配置文件

在原有的webservice的配置文件中加入下面一段配置:

<jaxws:inInterceptors>
	<bean class="com.neusoft.talentbase.platform.webservice.callback.MyInterceptor"/>
</jaxws:inInterceptors>

类似下图这样
在这里插入图片描述

2、编写拦截类

如上配置的bean中包路径创建类MyInterceptor,内容如下:

package com.neusoft.talentbase.platform.webservice.callback;


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.Node;

public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public MyInterceptor() {
		// 在调用方法之前调用拦截器
        super(Phase.PRE_INVOKE);
	}

	@Override
	public void handleMessage(SoapMessage message) throws Fault {

		List<Header> headers = message.getHeaders();

		if (headers == null || headers.size() == 0) {
			throw new Fault(new IllegalArgumentException("权限验证信息未通过"));
		}
		Header firstHeader = headers.get(0);
		Element ele = (Element) firstHeader.getObject();
		String userIds = null;
		String userPasses = null;
		try {

			Node firstChild = ele.getFirstChild();
			System.out.println(firstChild.getFirstChild().getNodeValue());
			Node lastChild = ele.getLastChild();
			System.out.println(lastChild.getFirstChild().getNodeValue());

			userIds = firstChild.getFirstChild().getNodeValue();

			userPasses = lastChild.getFirstChild().getNodeValue();
		} catch (Exception e) {
			throw new Fault(new IllegalArgumentException("用户名或者密码不正确"));
		}

		if (StringUtils.isBlank(userIds)) {
			throw new Fault(new IllegalArgumentException("用户名格式不对"));
		}

		if (StringUtils.isBlank(userIds)) {
			throw new Fault(new IllegalArgumentException("密码格式不对"));
		}

		if (!userIds.equals("hky") || !userPasses.equals("hky")) {
			throw new Fault(new IllegalArgumentException("用户名或者密码不正确"));
		}

	}

}

先把代码上全,后面再解释

3、接口测试程序TestWebservice

java中采取axis2调用测试代码,如下:

package com.neusoft.talentbase.staffing.employee.webService;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.axis2.util.Base64;

import com.neusoft.talentbase.platform.core.dao.blob.dto.MyBlobDTO;

public class TestWebservice {

	public static void main(String[] args) throws Exception {
		final String targetEndpoint = "http://localhost:8088/pl/service/getBlobWebservice";
		final String targetNamespace = "http://webService.employee.staffing.talentbase.neusoft.com/";
		final String method = "executeBlobById";
		String namespace = "http://webService.employee.staffing.talentbase.neusoft.com/";
		String paramData = "0386574e4aa54efb916b3cbd309a105d";
		RPCServiceClient client = null;
		try {
			client = new RPCServiceClient();
			Options options = client.getOptions();
			
			OMFactory factory = OMAbstractFactory.getOMFactory();
			OMNamespace SecurityElementNamespace = factory.createOMNamespace("http://handler.com", "wsse");
			OMElement authenticationOM = factory.createOMElement("Authentication", SecurityElementNamespace);
			OMElement usernameOM = factory.createOMElement("username", SecurityElementNamespace);
			OMElement passwordOM = factory.createOMElement("password", SecurityElementNamespace);
			usernameOM.setText("hky");
			passwordOM.setText("hky");
			authenticationOM.addChild(usernameOM);
			authenticationOM.addChild(passwordOM);
			client.addHeader(authenticationOM);
			
			options.setTo(new EndpointReference(targetEndpoint));
			//options.setTimeOutInMilliSeconds(1000 * 60 * 5);// 毫秒单位
			//options.setAction(targetNamespace + method);
			Object[] response = client.invokeBlocking(new QName(namespace, method), new Object[]{paramData}, new Class[]{MyBlobDTO.class});
			MyBlobDTO results = (MyBlobDTO) response[0];
			System.out.println("WebService请求返回结果: \r\n{}" + results.getName());
			results.setContent(Base64.decode(results.getCentent()));
			System.out.println(results.getCentent());
			System.out.println(results.getContent());
			System.out.println(results.getId());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

简单解释一下,其中的MyblobDTO是一个JavaBean,里面有一个元素content,是通过编码后的字符串,所以decode了一下,进行解码成字节数组。。。

4、调试过程

(1)代码调试
这里的调用时代码上面的demo是可以正常调用的,其大概原理就是,在调用时添加了header信息,而后,请求到server端时,先会走到拦截器部分MyInterceptor,MyInterceptor所做的工作就是读取cilent设置的header中用户名、密码,与预定的用户名密码是否一致,若一致,则不拦截,若不一致,则抛异常。
(2)SoapUi调试
尤其客户方面一般都是用SoapUi做调试工具,所以我需要给他们相应的头信息,而代码设置的头信息,其生成之后是什么样,我也不知道啊。
通过查资料,其实可以通过生成客户端代码,然后debug,打印发送的报文是什么样的。于是结合soapui给出的模板,推理出我的报文内容如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webService.employee.staffing.talentbase.neusoft.com/">
   <soapenv:Header>
   		<wsse:Authentication xmlns:wsse="http://handler.com"><wsse:username>hky</wsse:username><wsse:password>hky</wsse:password></wsse:Authentication>
   </soapenv:Header>
   <soapenv:Body>
      <web:executeBlobById>
         <arg0>0386574e4aa54efb916b3cbd309a105d</arg0>
      </web:executeBlobById>
   </soapenv:Body>
</soapenv:Envelope>

<soapenv:Header>中添加了header信息,我之所以放到一行上,然后用来调试是因为,有缩进格式的情况下,soapui会报出奇怪的错误,(此处坑爹啊!)什么soap:clicent啥的,讨人厌啊。

5、扩展思路

上面的例子,是最基础的实现,对于扩展方面,有把用户名密码提取到.properties文件里的,还可以进行多方校验等等,就不一一细说了,针对不同的需求做相应的处理即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值