云自無(wú)心水自閑

          天平山上白云泉,云自無(wú)心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          Tapestry中并沒(méi)有類(lèi)似于Spring Security這樣的專(zhuān)門(mén)的權(quán)限框架。對(duì)此Tapestry的作者Lewis認(rèn)為主要是用戶(hù)對(duì)于權(quán)限的要求實(shí)在太多變化了。他認(rèn)為很難抽象出一個(gè)通用的權(quán)限框架來(lái)滿足所有的用戶(hù),所以他干脆就不費(fèi)事去做這件事了。但其實(shí)我們很容易就能利用Tapestry已有的工具來(lái)完成類(lèi)似于SpringSecurity的功能。
          本文主要介紹如何實(shí)現(xiàn)類(lèi)似于SpringSecurity的jsp tag的功能。在Tapestry中,利用Components實(shí)現(xiàn)這一點(diǎn)非常容易。
          其基本原理是Tapestry5中一個(gè)頁(yè)面或者組件的渲染生成過(guò)程是基于一個(gè)狀態(tài)機(jī)和隊(duì)列完成的。這樣,渲染生成過(guò)程就被細(xì)分成了很多個(gè)小模塊,我們可以非常容易地覆寫(xiě)這些小模塊。具體內(nèi)容詳見(jiàn)官方文檔:http://tapestry.apache.org/tapestry5.1/guide/rendering.html。如果權(quán)限校驗(yàn)不通過(guò),我們就可以控制不顯示組件的內(nèi)容。
          我們這里就是主要依賴(lài)這個(gè)過(guò)程來(lái)實(shí)現(xiàn)在頁(yè)面這一層面對(duì)權(quán)限進(jìn)行校驗(yàn)和控制。
          代碼主要包含兩大部分,一個(gè)組件和一個(gè)用于權(quán)限控制的服務(wù)。
          參考了Tapestry-Spring-Security的實(shí)現(xiàn),我也將組件命名為IfRole(當(dāng)然,我們也可以和Tapestry-Spring-Security一樣,也再生成一個(gè)IfLoggedIn組件)。權(quán)限控制的服務(wù)我命名為:AuthenticationService。
          主要的實(shí)現(xiàn)思路:
          將AuthenticationService申明為SessionState變量。這樣這個(gè)變量就可以在所有的頁(yè)面和組件之間很方便地共享了。一般情況下,是在登錄頁(yè)面對(duì)AuthenticationService進(jìn)行賦值,而在退出頁(yè)面清空AuthenticationService這個(gè)變量。
          代碼(這部分代碼完全根據(jù)應(yīng)用的需求進(jìn)自行更改):
          AuthenticationService的代碼:
          public class AuthenticationService {
              
          private List<String> privilegeList;
              
          // privilegeList 的getter and setter

              
          public boolean checkPermission(String ifNotGranted, String ifAllGranted,
                      String ifAnyGranted) 
          {
                  
          if (((null == ifAllGranted) || "".equals(ifAllGranted))
                          
          && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
                          
          && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
                      
          return false;
                  }


                  
          if ((null != ifNotGranted) && !"".equals(ifNotGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifNotGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (privilegeList.contains(value)) {
                              
          return false;
                          }

                      }

                  }


                  
          if ((null != ifAllGranted) && !"".equals(ifAllGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifAllGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (!privilegeList.contains(value)) {
                              
          return false;
                          }

                      }

                  }


                  
          if ((null != ifAnyGranted) && !"".equals(ifAnyGranted)) {
                      StringTokenizer st 
          = new StringTokenizer(ifAnyGranted, ",");
                      
          while (st.hasMoreTokens()) {
                          String value 
          = st.nextToken();
                          
          if (privilegeList.contains(value)) {
                              
          return true;
                          }

                      }

                      
          return false;
                  }


                  
          return true;
              }

          }

          IfRole的代碼(這個(gè)類(lèi)需要放在Components目錄下):
          public class IfRole {
              
          /**
               * A comma-separated list of roles is supplied to one or more of the
               * following parameters. If none are supplied, the default behavior is to
               * forbid access. Behavior should be self-explanatory.
               
          */

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifAllGranted;

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifAnyGranted;

              @Parameter(required 
          = false, defaultPrefix = "literal")
              
          private String ifNotGranted;

              
          /**
               * An alternate {
          @link Block} to render if the test parameter is false. The default, null, means
               * render nothing in that situation.
               
          */

              @Parameter(name 
          = "else")
              
          private Block elseBlock;

              
          private boolean test;
             
              @SessionState
              
          private AuthenticationService auth;

              
          private boolean checkPermission() {
                  
          return auth.checkPermission(ifNotGranted, ifAllGranted, ifAnyGranted);
              }

             
              
          void setupRender() {
                  test 
          = checkPermission();
              }


              
          /**
               * Returns null if the test method returns true, which allows normal
               * rendering (of the body). If the test parameter is false, returns the else
               * parameter (this may also be null).
               
          */

              Object beginRender() 
          {
                  
          return test ? null : elseBlock;
              }


              
          /**
               * If the test method returns true, then the body is rendered, otherwise not. The component does
               * not have a template or do any other rendering besides its body.
               
          */

              
          boolean beforeRenderBody() {
                  
          return test;
              }

             
          }


          示例:
          1. 在登錄頁(yè)面:
          @SessionState
          private Authentication auth;

          ......

          // if user name and password is valid:
          auth.setPrivliegeList(.....);


          2. 在需要權(quán)限控制的頁(yè)面模板中:
          <t:ifRole ifAllGranted="admin">
                  administrator can see this block
          </t:ifRole>



          主站蜘蛛池模板: 施秉县| 潜江市| 陆河县| 驻马店市| 田林县| 铅山县| 德昌县| 云南省| 邢台县| 靖西县| 赫章县| 富民县| 平果县| 美姑县| 扶风县| 梁平县| 宁津县| 扶沟县| 宁德市| 景宁| 西安市| 浮梁县| 张掖市| 扶绥县| 日照市| 定襄县| 南开区| 罗田县| 鄂托克旗| 青铜峡市| 安阳县| 财经| 宁都县| 化州市| 海兴县| 泰和县| 顺昌县| 兴国县| 文登市| 灌云县| 漳平市|