当前位置: 代码迷 >> Web前端 >> 基于axis2开发受权web service
  详细解决方案

基于axis2开发受权web service

热度:245   发布时间:2013-09-25 11:02:59.0
基于axis2开发授权web service
本文服务端使用axis2发布web service服务,客户端采用两种方式实现:
1. 由wsdl文件生成stub客户端代码
2. 不生产stub代码,纯手工编写客户端

服务端代码如下:
1. service.xml配置文件如下,
<service name="WS"><!-- web service名称-->
	<description>Axis Service Description</description><!-- 接口描述-->
	<parameter name="ServiceClass">com.*.webservice.WSone</parameter><!-- 接口实现类-->
	<operation name="getPrice"><!-- 接口名称-->
		<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
	</operation>
	<operation name="updatePrice"><!-- 接口名称-->
		<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
	</operation>
	<operation name="sum"><!-- 接口名称-->
		<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
	</operation>
	
</service>



2. 接口实现类WSnoe代码如下,
import java.util.HashMap;
import org.apache.axis2.AxisFault;

public class WSone {
	private HashMap map = new HashMap();
	public double getPrice(String symbol) throws AxisFault {
		LoginCheck.checkUserPwd(); // 当客户端调用getPrice方法是,在此处先进行用户名和密码校验,如果校验通过则继续后续逻辑处理,如果不通过则抛出异常。
		Double price = (Double) map.get(symbol);
		if (price != null) {
			return price.doubleValue();
		}
		return 42.00;
	}

	public void updatePrice(String symbol, double price) throws AxisFault {
		LoginCheck.checkUserPwd(); // 在此处先进行用户名和密码校验,如果校验通过则继续后续逻辑处理,如果不通过则抛出异常。
		map.put(symbol, new Double(price));
	}

	public int sum(int num1, int num2) throws AxisFault {
		LoginCheck.checkUserPwd(); // 在此处先进行用户名和密码校验,如果校验通过则继续后续逻辑处理,如果不通过则抛出异常。
		return num1 + num2;
	}
}

服务端授权认证模块类是LoginCheck,本例中用户名和密码是定死的,可根据实际情况修改,内容如下:
import java.util.Iterator;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;

public class LoginCheck {
	public static void checkUserPwd() throws AxisFault {
		MessageContext msgContext = MessageContext.getCurrentMessageContext();
		Iterator list = (Iterator) msgContext.getEnvelope().getHeader().getFirstElement().getChildren();
		String Username = "";
		String Password = "";
		while (list.hasNext()) {
			OMElement element = (OMElement) list.next();
			if (element.getLocalName().equals("Username")) {
				Username = element.getText();
			}
			if (element.getLocalName().equals("Password")) {
				Password = element.getText();
			}
		}
		if (!Username.equals("toone") || !Password.equals("111")) {
			throw new AxisFault(" Authentication Fail! Check username/password ");
		}else{
			System.out.println("use:"+Username+"验证通过");
		}
	}
}


客户端代码如下:
客户端需要将包含认证用到的用户名和密码的OMElement对象放置到soap header中。
1. 包含用户名和密码的OMElement对象HeaderOMElement代码如下,
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

public class HeaderOMElement {
	public static OMElement createHeaderOMElement() {
		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("toone");
		passwordOM.setText("1111");
		authenticationOM.addChild(usernameOM);
		authenticationOM.addChild(passwordOM);
		return authenticationOM;
	}
}

2. 客户端代码实现方式1:不生成stub客户端代码
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import com.*.testws.HeaderOMElement;

public class PojoClient {
	public static void main(String[] args1)  {
		String serviceName = "http://localhost:8080/TestWS/services/WS";
		String namespace = "http://webservice.*.com";
		String methodName = "getPrice";
		Object[] methodArgs = new Object[] {};
		Class[] returnTypes = new Class[] { Double.class };
		try {
			RPCServiceClient serviceClient = new RPCServiceClient();
			// 将创建的OMElement对象放置到Header中
			serviceClient.addHeader(HeaderOMElement.createHeaderOMElement());
			Options options = serviceClient.getOptions();
			EndpointReference targetEPR = new EndpointReference(serviceName);
			options.setTo(targetEPR);
			QName op = new QName(namespace, methodName);
			Object[] response = serviceClient.invokeBlocking(op, methodArgs,returnTypes);
			Double result = (Double) response[0];
			if (result == null) {
				System.out.println("didn't initialize!");
				return;
			} else {
				System.out.println("Price ====== " + result.doubleValue());
			}
		} catch (AxisFault e) {
			System.out.println("验证失败");
			e.printStackTrace();
		}
	}

}


3. 客户端代码实现方式2:生成stub客户端代码
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.ServiceClient;
import com.*.webservice.WSStub;

public class TestClient {
	public static void main(String[] args) {
		try {
			WSStub stub = new WSStub("http://localhost:8080/TestWS/services/WS");
			ServiceClient sc = stub._getServiceClient();
			sc.addHeader(HeaderOMElement.createHeaderOMElement());
			stub._setServiceClient(sc);
			
			WSStub.Sum sums = new WSStub.Sum();
			sums.setNum1(2);
			sums.setNum2(3);
			WSStub.SumResponse sr = stub.sum(sums);
			System.out.println(sr.get_return());
			
			WSStub.GetPrice gp = new WSStub.GetPrice();
			gp.setSymbol("sino");
			WSStub.GetPriceResponse gpr = stub.getPrice(gp);
			System.out.println(gp.getSymbol()+" : "+gpr.get_return());
			
			WSStub.UpdatePrice up = new WSStub.UpdatePrice();
			up.setSymbol("sino");
			up.setPrice(100.0);
			stub.updatePrice(up);
			
			WSStub.GetPrice gpnew = new WSStub.GetPrice();
			gpnew.setSymbol("sino");
			WSStub.GetPriceResponse gprnew = stub.getPrice(gpnew);
			System.out.println(gpnew.getSymbol()+" : "+gprnew.get_return());

		}  catch (AxisFault e) {
			System.out.println("验证失败:"+e.getMessage());
			e.printStackTrace();
		}catch (RemoteException e) {
			System.out.println("远程连接失败:"+e.getMessage());
			e.printStackTrace();
		}
	}
}


以上授权实现,仅是用作授权认证机制,用户名和密码在soap消息传递过程中为明文传递,不能实现链路或信息加密。
使用TcpTrace工具进行抓包验证,参见链接:http://fxly0401.iteye.com/blog/1940119
  相关解决方案