<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    David.Turing's blog

     

    在SpringSide實(shí)現(xiàn)XFire Webservice認(rèn)證

    XFire官方網(wǎng)站提供的基于Webservice認(rèn)證的例子有問(wèn)題,在新版本的XFire1.1.2中編譯不通過(guò),不過(guò)這也是小Case,我后來(lái)折騰了一下,為SpringSide提供了一個(gè)簡(jiǎn)單的Webservice認(rèn)證功能。
    XFire跟Spring的天然融合,讓我們可以少努力10年就能簡(jiǎn)單地在Spring中使用Webservice的強(qiáng)大魅力,我從AXIS專向XFire有一些沖動(dòng),也吃了不少虧,但受REST一族的強(qiáng)力吹捧,感覺(jué)還是值得嘗試的,因此,在公司的系統(tǒng)中也把Axis徹底換了XFire。

    回到SpringSide,我大概介紹一下如何配置一個(gè)真正實(shí)用的XFire驗(yàn)證服務(wù)。
    SpringSide中的XFire配置文件放在:
    SpringSide-bookstore\src\org\springside\bookstore\plugins\webservice\applicationContext-webservice-server.xml
    我們?cè)诶锩娑x各個(gè)Webservice,該文件其實(shí)對(duì)應(yīng)于XFire官方的XFire-Servlet.xml
    看看下面的BookService,這是一個(gè)典型的Webservice服務(wù),紅色的inHandlers是我掛上去的。它的意思是所有訪問(wèn)BookService的請(qǐng)求都會(huì)被先送到authenticationHandler去處理,我們的驗(yàn)證邏輯可以在里面進(jìn)行。
    ????<!--Web Service 在SpringMVC中的URL 路徑映射-->
    ??? <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    ??????? <property name="mappings">
    ??????????? <value>/BookService=bookWebService</value>
    ??????? </property>
    ??????? <property name="inHandlers">
    ??????????? <ref bean="authenticationHandler"/>
    ??????? </property>

    ??? </bean>

    我們接著看看authenticationHandler的代碼:
    我們?cè)赟pringSide中通過(guò)header方式向服務(wù)器提供驗(yàn)證信息(另外一種更簡(jiǎn)單的方式是創(chuàng)建一個(gè)Login的webservice服務(wù),然后在XFire Session中建立Token信息)。
    package?org.springside.bookstore.plugins.webservice.authentication;

    import?org.apache.log4j.Logger;
    import?org.codehaus.xfire.MessageContext;
    import?org.codehaus.xfire.exchange.InMessage;
    import?org.codehaus.xfire.fault.XFireFault;
    import?org.codehaus.xfire.handler.AbstractHandler;
    import?org.jdom.Element;
    import?org.jdom.Namespace;


    /**
    ?*?XFire的回調(diào)的Handler,在XFire配置文件中配置
    ?*?Server端的認(rèn)證模塊,回調(diào)處理模塊
    ?*?
    ?*?ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用
    ?*?
    ?*?
    @author??david.turing
    ?*?@blog??openssl.blogjava.net
    ?*
    ?
    */
    public?class?AuthenticationHandler?extends?AbstractHandler?{
    ????
    private?static?final?Logger?log?=?Logger.getLogger(AuthenticationHandler.class);
    ????
    ????
    public?void?invoke(MessageContext?context)?throws?Exception?{
    ????????
    ????????log.info(
    "#AuthenticationHandler?is?invoked");
    ????????InMessage?message
    =context.getInMessage();
    ????????
    ????????
    final?Namespace?TOKEN_NS?=?Namespace.getNamespace("SpringSide","http://service.webservice.plugins.bookstore.springside.org");??
    ????????
    ????????
    if(message.getHeader()==null)
    ????????{
    ????????????
    throw?new?XFireFault("GetRelation?Service?Should?be?Authenticated",
    ????????????????????XFireFault.SENDER);
    ????????}
    ????????
    ????????Element?token?
    =?message.getHeader().getChild("AuthenticationToken",?TOKEN_NS);
    ????????
    if?(token?==?null)
    ????????{
    ????????????
    throw?new?XFireFault("Request?must?include?authentication?token.",
    ?????????????????????????????????XFireFault.SENDER);
    ????????}

    ????????String?username?
    =?token.getChild("Username",?TOKEN_NS).getValue();
    ????????String?password?
    =?token.getChild("Password",?TOKEN_NS).getValue();

    ????????System.out.println(
    "username="+username);????????
    ????????System.out.println(
    "password="+password);
    ????????
    ????????
    if(username==null||password==null)
    ????????????
    throw?new?XFireFault("Supplied?Username?and?Password?Please",
    ????????????????????XFireFault.SENDER);
    ????????
    ????????
    /**
    ?????????*?檢查用戶名密碼是否正確
    ?????????
    */
    ????????PasswordAuthenticationManager?pamanager
    =new?PasswordAuthenticationManager();
    ????????
    if(!pamanager.authenticate(username,password))
    ????????????
    throw?new?XFireFault("Authentication?Fail!?Check?username/password",
    ????????????????????XFireFault.SENDER);
    ?
    ????????
    ????}
    }
    注意,XFireFault異常是往客戶端拋的,Webservice Client應(yīng)該學(xué)會(huì)catch XFireFault.

    服務(wù)器端就是這么簡(jiǎn)單,看看客戶端的TestCase
    package?org.springside.bookstore.plugins.webservice.service;

    import?java.lang.reflect.Proxy;
    import?java.net.MalformedURLException;
    import?java.util.List;

    import?org.codehaus.xfire.client.Client;
    import?org.codehaus.xfire.client.XFireProxy;
    import?org.codehaus.xfire.client.XFireProxyFactory;
    import?org.codehaus.xfire.service.Service;
    import?org.codehaus.xfire.service.binding.ObjectServiceFactory;
    import?org.springside.bookstore.commons.domain.Book;
    import?org.springside.bookstore.plugins.webservice.authentication.ClientAuthHandler;

    import?junit.framework.TestCase;

    public?class?BookServiceWithAuthenticationTestCase?extends?TestCase?{

    ????
    protected?void?setUp()?throws?Exception?{
    ????????
    super.setUp();
    ????}

    ????
    protected?void?tearDown()?throws?Exception?{
    ????????
    super.tearDown();
    ????}
    ????
    ????
    public?void?getBookFromWebservice()?throws?Exception{
    ????
    ??????????Service?serviceModel?
    =?new?ObjectServiceFactory()
    ????????????????.create(BookService.
    class);
    ????????BookService?service?
    =?null;
    ????????
    ????????
    try?{
    ????????????service
    =(BookService)?new?XFireProxyFactory().create(
    ????????????????????serviceModel,
    ????????????????????
    "http://localhost:8080/springside/service/BookService");
    ????????}?
    catch?(MalformedURLException?e)?{
    ????????????e.printStackTrace();
    ????????}
    ????????
    ????????Client?client?
    =?((XFireProxy)?Proxy.getInvocationHandler(service)).getClient();
    ????????
    //掛上ClientAuthHandler,提供認(rèn)證
    ????????client.addOutHandler(new?ClientAuthHandler());
    ????????List?list?
    =?service.findBooksByCategory(null);
    ????????assertNotNull(list);
    ????????
    for(int?i=0;i<list.size();i++)
    ????????????System.out.println(((Book)list.get(i)).getName());
    ????}

    }

    你應(yīng)該看到上面的client.addOutHandler(new ClientAuthHandler());
    沒(méi)錯(cuò),它跟服務(wù)器端的AuthenticationHandler是一對(duì),一起使用的!
    也就是,每個(gè)被送往WebService服務(wù)的請(qǐng)求都被ClientAuthHandler處理過(guò)了。
    看看ClientAuthHandler做了些什么:
    package?org.springside.bookstore.plugins.webservice.authentication;

    import?org.apache.log4j.Logger;
    import?org.codehaus.xfire.MessageContext;
    import?org.codehaus.xfire.handler.AbstractHandler;
    import?org.jdom.Element;
    import?org.jdom.Namespace;

    /**
    ?*?客戶端端的認(rèn)證模塊,回調(diào)處理模塊
    ?*?每個(gè)需要認(rèn)證的WebService方法都可以掛這個(gè)Handler
    ?*?
    ?*?僅用于Demo,從解耦和易用性出發(fā),
    ?*?沒(méi)有跟Acegi結(jié)合,你可以任意擴(kuò)展
    ?*?默認(rèn)用戶名/密碼是admin/admin
    ?*?
    ?*?ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用
    ?*?
    ?*?
    @author??david.turing
    ?*
    ?*?@blog?openssl.blogjava.net
    ?
    */????
    public?class?ClientAuthHandler?extends?AbstractHandler?{
    ????????
    private?static?final?Logger?log?=?Logger.getLogger(ClientAuthHandler.class);
    ????????
    ????????
    //客戶端自己配置用戶名密碼或者更安全的KeyStore方式
    ????????private?String?username?=?"admin";
    ????????
    private?String?password?=?"admin";
    ????????
    ????????
    public?ClientAuthHandler()?{
    ????????}
    ????????
    ????????
    public?ClientAuthHandler(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方式
    ?????????????*?從Soap?Header中獲取用戶名密碼
    ?????????????******************************************
    */
    ????????????
    final?Namespace?ns?=?Namespace.getNamespace("SpringSide","http://service.webservice.plugins.bookstore.springside.org");??
    ????????????Element?el?
    =?new?Element("header",ns);

    ????????????Element?auth?
    =?new?Element("AuthenticationToken",?ns);
    ????????????Element?username_el?
    =?new?Element("Username",ns);
    ????????????username_el.addContent(username);
    ????????????Element?password_el?
    =?new?Element("Password",ns);
    ????????????password_el.addContent(password);
    ????????????auth.addContent(username_el);
    ????????????auth.addContent(password_el);
    ????????????el.addContent(auth);????????????
    ????????????context.getCurrentMessage().setHeader(el);????????????
    ????????????log.info(
    "ClientAuthHandler?done!");
    ????????}
    ????}

    不就是往header里面注入username,password!

    在SpringSide中,所有的Spring配置文件都被小白分散到各個(gè)Module中去了,Wuyu原先是在Plugin中提供Webservice功能,因此,我仍然在Plugin中創(chuàng)建XFire接口。
    SpringSide的Spring配置文件放在:
    SpringSide-bookstore\webapp\WEB-INF\springmvc-servlet.xml
    該文件定義了Plugin的xml:
    AuthenticationHandler這個(gè)Bean需要先定義在Plugins-servlet.xml中,其它很簡(jiǎn)單,大家去Try一下就知道了。

    posted on 2006-07-25 23:48 david.turing 閱讀(8785) 評(píng)論(4)  編輯  收藏 所屬分類: Security領(lǐng)域

    評(píng)論

    # re: 在SpringSide實(shí)現(xiàn)XFire Webservice認(rèn)證 2006-11-08 08:55 jcjack

    我有點(diǎn)不清楚的地方,想請(qǐng)教下,你的文章一再?gòu)?qiáng)調(diào):
    ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用。
    假如我提供一個(gè)web service面對(duì)不人的用戶,它們用可能使用java\ c#\ASP.....其他語(yǔ)言來(lái)中客戶端,這樣還有效果嗎?  回復(fù)  更多評(píng)論   

    # re: 在SpringSide實(shí)現(xiàn)XFire Webservice認(rèn)證 2007-05-14 15:04 freshman

    謝謝能踢過(guò)這個(gè)xfire的例子,我try了一下,很不錯(cuò),但如果客戶端是axis實(shí)現(xiàn)的話怎么辦?好像得到授權(quán)。axis里面也有handler的方式進(jìn)行認(rèn)證,但和xfire是不是不兼容?如果是c#呢?摟主能否再指點(diǎn)一二?  回復(fù)  更多評(píng)論   

    # re: 在SpringSide實(shí)現(xiàn)XFire Webservice認(rèn)證 2007-08-24 21:52 ianwong

    謝謝david,我按照你的文章已經(jīng)調(diào)通.
    我想如果是采用其他語(yǔ)言來(lái)開(kāi)發(fā)客虎端的話,只需要傳遞soapheader,里面含有相同命名空間的用戶密碼就行了吧.  回復(fù)  更多評(píng)論   

    # re: 在SpringSide實(shí)現(xiàn)XFire Webservice認(rèn)證[未登錄](méi) 2008-01-05 11:30 jason

    Service serviceModel = new ObjectServiceFactory()
    .create(BookService.class);
    在創(chuàng)建客戶端的服務(wù)時(shí),create(class)的參數(shù)BookService是從哪里來(lái)的呢?  回復(fù)  更多評(píng)論   

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(110)

    我參與的團(tuán)隊(duì)

    隨筆分類(126)

    隨筆檔案(155)

    文章分類(9)

    文章檔案(19)

    相冊(cè)

    搜索

    積分與排名

    最新隨筆

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲精品视频免费看| 13小箩利洗澡无码视频网站免费| 日美韩电影免费看| 色播在线永久免费视频| 国产又长又粗又爽免费视频| 亚洲精品老司机在线观看| 亚洲国产精品嫩草影院在线观看| 久久亚洲日韩看片无码| 国产性爱在线观看亚洲黄色一级片 | 美女巨胸喷奶水视频www免费| 青柠影视在线观看免费| 午夜无码A级毛片免费视频| AA免费观看的1000部电影| 国产婷婷高清在线观看免费| 77777亚洲午夜久久多人| 亚洲欧洲日韩国产综合在线二区| 33333在线亚洲| 特级无码毛片免费视频| 日韩精品免费视频| 成人性生交大片免费看午夜a| 四虎精品视频在线永久免费观看| 午夜私人影院免费体验区| 亚洲成a人片在线播放| 亚洲综合无码一区二区| 亚洲成av人片在www鸭子| 最近国语视频在线观看免费播放| 69天堂人成无码麻豆免费视频| 国产婷婷高清在线观看免费| 久久亚洲精精品中文字幕| 亚洲暴爽av人人爽日日碰| 国产成人AV免费观看| 女人18毛片水真多免费看| 亚洲综合熟女久久久30p| 亚洲一区二区三区在线网站| 九九综合VA免费看| 色se01短视频永久免费| 337p日本欧洲亚洲大胆裸体艺术| 久久久久se色偷偷亚洲精品av | 久久精品成人免费观看97| 91视频国产免费| 亚洲日韩欧洲乱码AV夜夜摸|