WebSerice是一种开放的web服务,任何人都可以访问,但我们有时候需要考虑只有付费用户才能使用WS,所以,我们就需要对WS加入安全验证机制,当然,可以利用防火墙的IP过滤,web应用的配置从最外层去隔离非法用户,但在内层,我们也可以使用SOAP Header的方式,由客户端发送验证数据,服务端验通过后基WS访问权限。
本实例为XFire+Spring,通过Spring的org.springframework.web.servlet.DispatcherServlet直接将XFire与Spring集成。
首先,编写服务端验证类继承AbstractHandler
import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.handler.AbstractHandler; import org.jdom.Element; public class AuthenticationHandler extends AbstractHandler ...{ public void invoke(MessageContext cfx) throws Exception ...{ if(cfx.getInMessage().getHeader() == null) ...{ throw new org.codehaus.xfire.fault.XFireFault("请求必须包含验证信息",org.codehaus.xfire.fault.XFireFault.SENDER); } Element token=cfx.getInMessage().getHeader().getChild("AuthenticationToken"); if (token == null) ...{ throw new org.codehaus.xfire.fault.XFireFault("请求必须包含身份验证信息", org.codehaus.xfire.fault.XFireFault.SENDER); } String username = token.getChild("Username").getValue(); String password = token.getChild("Password").getValue(); try ...{ //进行身份验证 ,只有abcd@1234的用户为授权用户 if(username.equals("abcd") && password.equals("1234")) //这语句不显示 System.out.println("身份验证通过"); else throw new Exception(); } catch (Exception e) ...{ throw new org.codehaus.xfire.fault.XFireFault("非法的用户名和密码", org.codehaus.xfire.fault.XFireFault.SENDER); } } }
接着,在客户端编写类继承AbstractHandler
import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.handler.AbstractHandler; import org.jdom.Element; public class ClientAuthenticationHandler extends AbstractHandler ...{ private String username = null; private String password = null; public ClientAuthenticationHandler() ...{ } public ClientAuthenticationHandler(String username,String password) ...{ this.username = username; this.password = password; } public void setUsername(String username) ...{ this.username = username; } public void setPassword(String password) ...{ this.password = password; } public void invoke(MessageContext context) throws Exception ...{ //为SOAP Header构造验证信息 Element el = new Element("header"); context.getOutMessage().setHeader(el); Element auth = new Element("AuthenticationToken"); Element username_el = new Element("Username"); username_el.addContent(username); Element password_el = new Element("Password"); password_el.addContent(password); auth.addContent(username_el); auth.addContent(password_el); el.addContent(auth); } }
然后,在调用WebService的客户端中加入如下代码
client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));
同时修改xfire-servlet.xml,绑定Handler
<bean id="queryMessageServiceExporter" class="org.codehaus.xfire.spring.remoting.XFireExporter"> <property name="serviceFactory"> <ref bean="xfire.serviceFactory" /> </property> <property name="xfire"> <ref bean="xfire" /> </property> <property name="serviceBean"> <ref bean="queryMessageBean" /> </property> <property name="serviceClass"> <value> zcpt.transfermessage.webservice.IQueryMessageService </value> </property> <property name="namespace"> <value> http://zcpt.transfermessage/QueryMessageService </value> </property> <property name="inHandlers"> <ref bean="AuthenticationHandler" /> </property> </bean> <bean id="AuthenticationHandler" class="zcpt.transfermessage.util.AuthenticationHandler"> </bean>
使用abcd@1234,可以正常访问WS,如果用错误帐号,则会报异常