WebSerice是一種開(kāi)放的web服務(wù),任何人都可以訪問(wèn),但我們有時(shí)候需要考慮只有付費(fèi)用戶才能使用WS,所以,我們就需要對(duì)WS加入安全驗(yàn)證機(jī)制,當(dāng)然,可以利用防火墻的IP過(guò)濾,web應(yīng)用的配置從最外層去隔離非法用戶,但在內(nèi)層,我們也可以使用SOAP Header的方式,由客戶端發(fā)送驗(yàn)證數(shù)據(jù),服務(wù)端驗(yàn)通過(guò)后基WS訪問(wèn)權(quán)限
首先根據(jù)我的這篇Blog
http://blog.csdn.net/daryl715/archive/2007/07/25/1707161.aspx
配置WS Server和WS Client,其中Client端的測(cè)試代碼類(lèi)名由Client改為ClientTest,因?yàn)槲覀円玫絏fire的一個(gè)名為Client的類(lèi)
首先我們編寫(xiě)服務(wù)端驗(yàn)證類(lèi)繼承AbstractHandler
package test;

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("請(qǐng)求必須包含驗(yàn)證信息",org.codehaus.xfire.fault.XFireFault.SENDER);
}
Element token=cfx.getInMessage().getHeader().getChild("AuthenticationToken");
if (token == null)

...{
throw new org.codehaus.xfire.fault.XFireFault("請(qǐng)求必須包含身份驗(yàn)證信息", org.codehaus.xfire.fault.XFireFault.SENDER);
}

String username = token.getChild("Username").getValue();
String password = token.getChild("Password").getValue();
try

...{
//進(jìn)行身份驗(yàn)證 ,只有abcd@1234的用戶為授權(quán)用戶
if(username.equals("abcd") && password.equals("1234"))
//這語(yǔ)句不顯示
System.out.println("身份驗(yàn)證通過(guò)");
else throw new Exception();
}
catch (Exception e)

...{
throw new org.codehaus.xfire.fault.XFireFault("非法的用戶名和密碼", org.codehaus.xfire.fault.XFireFault.SENDER);
}

}



}

下面是Client發(fā)送授權(quán)信息
package test;

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構(gòu)造驗(yàn)證信息
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);
}



}

為ClientTest.java加入以下代碼
XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
Client client = proxy.getClient();
client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));
等等,還沒(méi)有完,修改Services.xm為WS綁定Handler
<?xml version="1.0" encoding="UTF-8"?>


<beans>
<service xmlns="http://xfire.codehaus.org/config/1.0">
<name>HelloService</name>
<namespace>http://test/HelloService</namespace>
<serviceClass>test.IHelloService</serviceClass>
<implementationClass>test.HelloServiceImpl</implementationClass>
<inHandlers>
<handler handlerClass ="test.AuthenticationHandler" ></handler >
</inHandlers>
</service>
</beans>
這樣我們就完成了編碼,下面啟動(dòng)tomcat,運(yùn)行客戶端代碼,本文為abcd@1234位授權(quán)用戶,使用abcd@1234,可以正常訪問(wèn)WS,如果用錯(cuò)誤帳號(hào),則會(huì)有以下異常
Exception in thread "main" org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: 非法的用戶名和密碼
org.codehaus.xfire.fault.XFireFault: 非法的用戶名和密碼
at org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)
at org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Client.onReceive(Client.java:406)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
at org.codehaus.xfire.client.Client.invoke(Client.java:336)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy0.getUser(Unknown Source)
at test.ClientTest.main(ClientTest.java:39)

如果不在CientTest加以下增加Heade則會(huì)有以下異常
XFireProxy proxy = (XFireProxy)Proxy.getInvocationHandler(service);
Client client = proxy.getClient();
client.addOutHandler(new ClientAuthenticationHandler("abcd1","1234"));
Exception in thread "main" org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: 請(qǐng)求必須包含驗(yàn)證信息
org.codehaus.xfire.fault.XFireFault: 請(qǐng)求必須包含驗(yàn)證信息
at org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)
at org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:111)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Client.onReceive(Client.java:406)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
at org.codehaus.xfire.client.Client.invoke(Client.java:336)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy0.getUser(Unknown Source)
at test.ClientTest.main(ClientTest.java:35)