隨筆-11  評論-16  文章-1  trackbacks-0

          第二章 登錄及 URL攔截

           

           

          本章講解如何控制用戶登錄,如何攔截 URL 進行權限驗證。

           

          通常,項目有這樣的需求:

           

          1. 某些頁面沒有登錄可以查看;
          2. 某些頁面必須登錄才能查看,如果沒有登錄,轉移到登錄頁面,成功登錄后再轉移回來;
          3. 某些頁面必須驗證當前登錄用戶是否具有請求該頁面的權限,如果沒有轉移到權限不足提示界面。

           

          解決思路

          控制登錄

          控制用戶登錄,采用 Filter 機制,不妨給該 Filter 起名為 LoginFilter 。

          怎樣控制哪些頁面驗證是否登錄,哪些又不需要呢?配置 web.xml , filter 元素的 url-pattern 屬性就可以了。

          如:

          Xml代碼 
          1. <filter-mapping>  
          2.               <filter-name>LoginFilter</filter-name>  
          3.               <url-pattern>/secretDir/*</url-pattern>  
          4. </filter-mapping>  
          5.   
          6. <filter-mapping>  
          7.               <filter-name>LoginFilter</filter-name>  
          8.               <url-pattern>/anotherDir/secretDir/*</url-pattern>  
          9. </filter-mapping>  
           

           

           

          LoginFilter 檢查 session 是否有用戶,如果沒有轉移到登錄頁面;否則繼續執行。

          偽代碼如下:

          Java代碼 
          1. if( session.getAttribute( “user” )==null ) {  
          2.        // 將用戶期望請求頁面保存到session,供用戶登錄成功后,自動跳轉使用  
          3.        String requestUrl=…;  
          4.        session.setAttribute( “requestUrl”, requestUrl );   
          5.   
          6.        // 轉移到登錄界面  
          7.        redirect( loginPage, request, response );  
          8.        return;  
          9. }  
          10.   
          11. filter.doChain( request, response );  
           

           

           

          LoginFilter 還可以更進一步,處理用戶提交用戶名和密碼后驗證。只要告訴 LoginFilter 用戶名是哪個 parameter name ,密碼是哪個parameter name ,密碼采用了什么加密算法,就可以了。

          偽代碼如下:

          Java代碼 
          1. String username=request.getParameter( usernameParameterName );  
          2. String password=request.getParameter( passwordParameterName );  
          3. String secretPassword=encrypt(encryptMethod, password );  
          4.    
          5.   
          6. User user=userManager.checkUser( username, secretPassword );  
          7. if( user==null ) {  
          8.        // 驗證不通過,繼續轉移到登錄界面  
          9.        redirect( loginPage, request, response );  
          10. else {  
          11.        // 驗證通過,將用戶保存到session,然后繼續處理  
          12.        session.removeAttribute( “requestUrl” );  
          13.        session.setAttribute( “user”, user );  
          14.        filter.doChain( request, response );  
          15. }  
           

           

           

          細心的朋友,會問轉移到原來期望請求的頁面,怎么沒有看到邏輯呢?

          是的,可以在該 filter 里面 redirect 。但我更傾向于在登錄界面的 action 做處理。偽代碼如下:

          Html代碼 
          1. <%  
          2. String url=defaultLoginPage;  
          3. String requestUrl= (String)session.getAttribute( “requestUrl” );  
          4. if(requestUrl!=null ) {  
          5.     urlrequestUrl;  
          6. }  
          7. %>  
          8. <form method=”post” action=”<%=url%>>  
          9. …  
          10. </form>  
           

           

          攔截 url 做權限判斷

          對于 web 系統,權限表有這么幾個字段:標識、名稱、描述、對應 url 。

          那么對于 url 請求,可以在權限表進行查找,查看該 url 是否有個對應的權限。如果有,說明該 url 需要具有沒個權限才能訪問,那么通過 RBAC 算法進行判斷即可。如果在權限表沒有找到對應記錄,說明該 url 不需要進行權限驗證。

           

          該需求比較簡單,也可以采用 Filter 機制,不妨取名 UrlAclFilter 。

           

          唯一需要注意的地方是:權限表對應的 url 可能帶有參數。比如 customreManager?op=add 是增加客戶權限, customerManager?op=delete 是刪除客戶權限。

           

          偽代碼如下:

          Java代碼 
          1. if( needPrivilegeCheck( request ) ) {  
          2.     // 需要做權限判斷  
          3.     if( session.getAttribute( “user” ) ==null ) {  
          4.         // 用戶還沒有登錄,轉移到登錄界面  
          5.         redirect( loginPage, request, response );  
          6.         return;  
          7.     } else {  
          8.         if( userManager.hasPrivilege( user, privilegeId ) ) {  
          9.             filter.doChain( request, response );  
          10.             return;  
          11.         } else {  
          12.             redirect( forbiddenHintPage, request, response );  
          13.             return;  
          14.         }  
          15.     }  
          16. }  
           

           

          基礎數據庫表

          用戶信息表,保存用戶信息還有密碼等,有的系統會對密碼進行加密保存到數據庫,而不是以明文的形式保存到數據庫。

           

          權限表,該表基本有這么幾個字段:標識、名稱、描述、指向 url 、 target 。 target 表示點擊該 Url 時在那個窗口顯示。標識為主鍵。

          比如下圖所示 frameset ,權限菜單 target 屬性應該是: MAIN

          角色表,該表字段:標識、名稱、描述;標識為主鍵。

          權限-角色關系表,該表有字段:角色標識、權限標識;角色標識和權限標識為復合主鍵。

          用戶-角色關系表,該表有字段:用戶標識、角色標識;用戶標識和角色標識為復合主鍵。

           

          如果使用 Metadmin

          使用 Metadmin ,只要在 web.xml 里面,配置 LoginFilter 和 UrlAclFilter 即可。

          (在 www.metadmin.com, 免費下載90天試用版)

          下面就是一個示例配置,對 metadmin/demo 目錄進行登錄和 url 攔截權限驗證,登錄頁面是 metadmin/demo/login.jsp 頁面。

          具體參數意義可查看 JAVADOC : http://www.metadmin.com/doc/javadoc/index.html LoginFilter 和 UrlAclFilter 。

           

          配置示例:

          Xml代碼 
          1.       <filter>  
          2.     <filter-name>metadmin/LoginFilter</filter-name>  
          3.     <filter-class>org.back.webFilter.LoginFilter</filter-class>  
          4.     <init-param>  
          5.         <param-name>loginPage</param-name>  
          6.         <param-value>/metadmin/demo/login.jsp</param-value>  
          7.     </init-param>  
          8.     <init-param>  
          9.         <param-name>uniqueFieldsParams</param-name>  
          10.         <param-value>loginName</param-value>  
          11.     </init-param>  
          12.     <init-param>  
          13.         <param-name>passwordParam</param-name>  
          14.         <param-value>password</param-value>  
          15.     </init-param>  
          16.     <!--init-param>  
          17.         <param-name>encryptMethod</param-name>  
          18.         <param-value>shahex</param-value>  
          19.     </init-param-->  
          20. </filter>  
          21. <filter>  
          22.     <filter-name>metadmin/UrlAclFilter</filter-name>  
          23.     <filter-class>org.back.webFilter.UrlAclFilter</filter-class>  
          24.     <init-param>  
          25.         <param-name>loginPage</param-name>  
          26.         <param-value>/metadmin/demo/login.jsp</param-value>  
          27.     </init-param>  
          28.     <init-param>  
          29.         <param-name>denyPage</param-name>  
          30.         <param-value>/metadmin/demo/noPrivilege.jsp</param-value>  
          31.     </init-param>  
          32. </filter>  
          33.   
          34.      <filter-mapping>  
          35.     <filter-name>metadmin/LoginFilter</filter-name>  
          36.     <url-pattern>/metadmin/demo/*</url-pattern>  
          37. </filter-mapping>  
          38. <filter-mapping>  
          39.     <filter-name>metadmin/UrlAclFilter</filter-name>  
          40.     <url-pattern>/metadmin/demo/*</url-pattern>  
          41. </filter-mapping>  
           

           

          posted on 2009-06-16 15:39 細粒度權限管理 閱讀(3008) 評論(4)  編輯  收藏

          評論:
          # re: 《玩轉細粒度權限管理》 二,登錄及URL攔截 2009-06-17 00:42 | 心夢帆影
          細精度權限管理,這個主題不錯,支持一下.  回復  更多評論
            
          # re: 《玩轉細粒度權限管理》 二,登錄及URL攔截 2009-06-17 08:12 | 細粒度權限管理
          @心夢帆影
          謝謝支持!還會有后繼文章的。歡迎關注!  回復  更多評論
            
          # re: 《玩轉細粒度權限管理》 二,登錄及URL攔截[未登錄] 2009-06-17 11:08 | Sniper
          關注中!  回復  更多評論
            
          # re: 《玩轉細粒度權限管理》 二,登錄及URL攔截 2009-06-23 10:03 | 找個美女做老婆
          Java樂園技術交流,http://www.javaly.cn
          2群群號:28840096  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 三门峡市| 鹤庆县| 昌江| 苏尼特右旗| 鄯善县| 始兴县| 鄂托克前旗| 洛阳市| 芒康县| 承德市| 昔阳县| 庐江县| 江西省| 上栗县| 吉林省| 龙岩市| 洪江市| 万宁市| 乐山市| 会理县| 鄂伦春自治旗| 新邵县| 新兴县| 延津县| 南昌市| 西贡区| 兴仁县| 东宁县| 都安| 罗定市| 贺兰县| 汉川市| 建平县| 临高县| 泽州县| 泰安市| 伊川县| 崇左市| 彭阳县| 迁安市| 突泉县|