<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實現XFire Webservice認證

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

    回到SpringSide,我大概介紹一下如何配置一個真正實用的XFire驗證服務。
    SpringSide中的XFire配置文件放在:
    SpringSide-bookstore\src\org\springside\bookstore\plugins\webservice\applicationContext-webservice-server.xml
    我們在里面定義各個Webservice,該文件其實對應于XFire官方的XFire-Servlet.xml
    看看下面的BookService,這是一個典型的Webservice服務,紅色的inHandlers是我掛上去的。它的意思是所有訪問BookService的請求都會被先送到authenticationHandler去處理,我們的驗證邏輯可以在里面進行。
    ????<!--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的代碼:
    我們在SpringSide中通過header方式向服務器提供驗證信息(另外一種更簡單的方式是創建一個Login的webservice服務,然后在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的回調的Handler,在XFire配置文件中配置
    ?*?Server端的認證模塊,回調處理模塊
    ?*?
    ?*?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應該學會catch XFireFault.

    服務器端就是這么簡單,看看客戶端的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,提供認證
    ????????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());
    ????}

    }

    你應該看到上面的client.addOutHandler(new ClientAuthHandler());
    沒錯,它跟服務器端的AuthenticationHandler是一對,一起使用的!
    也就是,每個被送往WebService服務的請求都被ClientAuthHandler處理過了。
    看看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;

    /**
    ?*?客戶端端的認證模塊,回調處理模塊
    ?*?每個需要認證的WebService方法都可以掛這個Handler
    ?*?
    ?*?僅用于Demo,從解耦和易用性出發,
    ?*?沒有跟Acegi結合,你可以任意擴展
    ?*?默認用戶名/密碼是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配置文件都被小白分散到各個Module中去了,Wuyu原先是在Plugin中提供Webservice功能,因此,我仍然在Plugin中創建XFire接口。
    SpringSide的Spring配置文件放在:
    SpringSide-bookstore\webapp\WEB-INF\springmvc-servlet.xml
    該文件定義了Plugin的xml:
    AuthenticationHandler這個Bean需要先定義在Plugins-servlet.xml中,其它很簡單,大家去Try一下就知道了。

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

    評論

    # re: 在SpringSide實現XFire Webservice認證 2006-11-08 08:55 jcjack

    我有點不清楚的地方,想請教下,你的文章一再強調:
    ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用。
    假如我提供一個web service面對不人的用戶,它們用可能使用java\ c#\ASP.....其他語言來中客戶端,這樣還有效果嗎?  回復  更多評論   

    # re: 在SpringSide實現XFire Webservice認證 2007-05-14 15:04 freshman

    謝謝能踢過這個xfire的例子,我try了一下,很不錯,但如果客戶端是axis實現的話怎么辦?好像得到授權。axis里面也有handler的方式進行認證,但和xfire是不是不兼容?如果是c#呢?摟主能否再指點一二?  回復  更多評論   

    # re: 在SpringSide實現XFire Webservice認證 2007-08-24 21:52 ianwong

    謝謝david,我按照你的文章已經調通.
    我想如果是采用其他語言來開發客虎端的話,只需要傳遞soapheader,里面含有相同命名空間的用戶密碼就行了吧.  回復  更多評論   

    # re: 在SpringSide實現XFire Webservice認證[未登錄] 2008-01-05 11:30 jason

    Service serviceModel = new ObjectServiceFactory()
    .create(BookService.class);
    在創建客戶端的服務時,create(class)的參數BookService是從哪里來的呢?  回復  更多評論   

    導航

    統計

    常用鏈接

    留言簿(110)

    我參與的團隊

    隨筆分類(126)

    隨筆檔案(155)

    文章分類(9)

    文章檔案(19)

    相冊

    搜索

    積分與排名

    最新隨筆

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 全部免费国产潢色一级| 1区1区3区4区产品亚洲| 亚洲综合色成在线播放| 久久久久亚洲精品无码蜜桃| 伊人免费在线观看| 亚洲精品无码久久千人斩| 亚洲精品久久无码av片俺去也| 无码免费午夜福利片在线| 亚洲女子高潮不断爆白浆| 91精品国产免费入口| 亚洲AV人无码激艳猛片| 91精品手机国产免费| 亚洲国产系列一区二区三区| 国产精品99精品久久免费| 久久亚洲AV无码精品色午夜麻| 久久综合给合久久国产免费| 4480yy私人影院亚洲| 日韩不卡免费视频| mm1313亚洲国产精品无码试看 | 亚洲欧洲精品成人久久曰| 日本高清免费不卡视频| 免费又黄又爽又猛大片午夜| 成人午夜性A级毛片免费| 18禁亚洲深夜福利人口| 亚洲自偷自偷偷色无码中文| 57pao一国产成永久免费| 亚洲乱码在线观看| AV在线播放日韩亚洲欧| 91高清免费国产自产拍2021| 伊人久久五月丁香综合中文亚洲| ww在线观视频免费观看| 亚洲av纯肉无码精品动漫| 在线亚洲精品福利网址导航| 亚洲视频免费在线播放| 美女无遮挡免费视频网站| 亚洲成在人天堂一区二区| 成人免费视频88| 久久国产精品国产自线拍免费| 在线a亚洲v天堂网2019无码| 1000部夫妻午夜免费 | 亚洲综合亚洲综合网成人|