XFire Web Service驗(yàn)證方案
Posted on 2008-03-03 11:26 semovy 閱讀(1159) 評(píng)論(0) 編輯 收藏 所屬分類: WebServiceHttpServletResponse response = XFireServletController.getResponse();
此條路不通只好去查XFire的文檔關(guān)于authentication部分,大概有以下幾種方案:
-
HTTP Authentication
-
SOAP Header authentication with JSR181
-
SOAP authentication with handlers
-
WS-Security
// Create your client
Client client = ....;
// Or get it from your proxy
Client client = ((XFireProxy) Proxy.getInvocationHandler(myClientProxy)).getClient();
client.setProperty(Channel.USERNAME, "username");
client.setProperty(Channel.PASSWORD, "pass");
去忘了寫服務(wù)端應(yīng)該怎么做,這個(gè)username和password該在那里驗(yàn)證呢??我翻遍了文檔也沒(méi)找著
來(lái)看第二條SOAP header authentication with JSR181,看起來(lái)倒是很簡(jiǎn)單
但是在Service的代碼中每個(gè)方法里都要寫一個(gè)UserToken驗(yàn)證的參數(shù),雖然似乎權(quán)限粒度能控制得很細(xì),但是這嚴(yán)重污染了業(yè)務(wù)邏輯的代碼,非常的不優(yōu)雅,放棄!
public void someOperation(String data, @WebParam(header=true) UserToken token) {
authenticate(token)
// do your normal request here
}
再看WS-Security,這是webservice的安全標(biāo)準(zhǔn),但實(shí)在太復(fù)雜了,并且需要配置Service.xml,我們項(xiàng)目是Java1.5,Service.xml根本就沒(méi)有寫,是自動(dòng)生成的,我是實(shí)在找不到Service.xml該在那配置?只好作罷
文檔里遺漏了很重要的一點(diǎn),就是關(guān)于如何在xfire-servlet里配置,導(dǎo)致很多人看了文檔也進(jìn)行不下去,我查了很久才在老外的一篇blog里找到一點(diǎn)tips,下面是配置:
<!-- WebService base, do not modify it -->
<bean id="webService" class="org.codehaus.xfire.spring.remoting.XFireExporter" abstract="true">
<property name="serviceFactory">
<ref bean="xfire.serviceFactory" />
</property>
<property name="xfire">
<ref bean="xfire" />
</property>
</bean>
<bean id="yourWebService" parent="webService">
<property name="serviceBean">
<ref bean="yourService" />
</property>
<property name="serviceClass">
<value>your.package.YourServiceInterface</value>
</property>
<property name="inHandlers">
<ref bean="authenticationHandler"/>
</property>
</bean>
AuthenticationHandler需要修改一下,其他不用變:
AuthenticationHandler.java
import org.apache.log4j.Logger;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.handler.AbstractHandler;
import org.codehaus.xfire.fault.*;
import org.jdom.*;
public class AuthenticationHandler extends AbstractHandler {
private static final Logger log = Logger.getLogger(AuthenticationHandler.class);
public void invoke(MessageContext context) throws Exception {
log.info("authentication handler is invoked");
if (context.getInMessage().getHeader() == null)
{
throw new XFireFault("Request must include company authentication token.",
XFireFault.SENDER);
}
Element header = context.getInMessage().getHeader();
Element token = header.getChild("AuthenticationToken");
if (token == null)
{
throw new XFireFault("Request must include authentication token.",
XFireFault.SENDER);
}
String username = token.getChild("Username").getText();
String password = token.getChild("Password").getText();
try {
// 現(xiàn)在你已經(jīng)得到了客戶端傳來(lái)的username和password,那就驗(yàn)證它吧(可以交給acegi來(lái)驗(yàn)證)
}
}catch(Exception e) {
log.warn(e);
throw new XFireFault("Authentication Failed.",
XFireFault.SENDER);
}
}
}
客戶端代碼:
YourService service = (YourService) new XFireProxyFactory().create(serviceModel,
"http://localhost:8080/YourProject/service/YourService");
Client client = proxy.getClient();
client.addOutHandler(new ClientAuthHandler("jeffrey", "killjava"));
// 執(zhí)行下面代碼會(huì)進(jìn)行驗(yàn)證
service.someOperation();