第二章 登錄及 URL攔截
本章講解如何控制用戶登錄,如何攔截 URL 進行權限驗證。
通常,項目有這樣的需求:
- 某些頁面沒有登錄可以查看;
- 某些頁面必須登錄才能查看,如果沒有登錄,轉移到登錄頁面,成功登錄后再轉移回來;
- 某些頁面必須驗證當前登錄用戶是否具有請求該頁面的權限,如果沒有轉移到權限不足提示界面。
解決思路
控制登錄
控制用戶登錄,采用 Filter 機制,不妨給該 Filter 起名為 LoginFilter 。
怎樣控制哪些頁面驗證是否登錄,哪些又不需要呢?配置 web.xml , filter 元素的 url-pattern 屬性就可以了。
如:
- <filter-mapping>
- <filter-name>LoginFilter</filter-name>
- <url-pattern>/secretDir/*</url-pattern>
- </filter-mapping>
-
- <filter-mapping>
- <filter-name>LoginFilter</filter-name>
- <url-pattern>/anotherDir/secretDir/*</url-pattern>
- </filter-mapping>
LoginFilter 檢查 session 是否有用戶,如果沒有轉移到登錄頁面;否則繼續執行。
偽代碼如下:
- if( session.getAttribute( “user” )==null ) {
-
- String requestUrl=…;
- session.setAttribute( “requestUrl”, requestUrl );
-
-
- redirect( loginPage, request, response );
- return;
- }
-
- filter.doChain( request, response );
LoginFilter 還可以更進一步,處理用戶提交用戶名和密碼后驗證。只要告訴 LoginFilter 用戶名是哪個 parameter name ,密碼是哪個parameter name ,密碼采用了什么加密算法,就可以了。
偽代碼如下:
- String username=request.getParameter( usernameParameterName );
- String password=request.getParameter( passwordParameterName );
- String secretPassword=encrypt(encryptMethod, password );
-
-
- User user=userManager.checkUser( username, secretPassword );
- if( user==null ) {
-
- redirect( loginPage, request, response );
- } else {
-
- session.removeAttribute( “requestUrl” );
- session.setAttribute( “user”, user );
- filter.doChain( request, response );
- }
細心的朋友,會問轉移到原來期望請求的頁面,怎么沒有看到邏輯呢?
是的,可以在該 filter 里面 redirect 。但我更傾向于在登錄界面的 action 做處理。偽代碼如下:
- <%
- String url=defaultLoginPage;
- String requestUrl= (String)session.getAttribute( “requestUrl” );
- if(requestUrl!=null ) {
- url= requestUrl;
- }
- %>
- <form method=”post” action=”<%=url%>”>
- …
- </form>
攔截 url 做權限判斷
對于 web 系統,權限表有這么幾個字段:標識、名稱、描述、對應 url 。
那么對于 url 請求,可以在權限表進行查找,查看該 url 是否有個對應的權限。如果有,說明該 url 需要具有沒個權限才能訪問,那么通過 RBAC 算法進行判斷即可。如果在權限表沒有找到對應記錄,說明該 url 不需要進行權限驗證。
該需求比較簡單,也可以采用 Filter 機制,不妨取名 UrlAclFilter 。
唯一需要注意的地方是:權限表對應的 url 可能帶有參數。比如 customreManager?op=add 是增加客戶權限, customerManager?op=delete 是刪除客戶權限。
偽代碼如下:
- if( needPrivilegeCheck( request ) ) {
-
- if( session.getAttribute( “user” ) ==null ) {
-
- redirect( loginPage, request, response );
- return;
- } else {
- if( userManager.hasPrivilege( user, privilegeId ) ) {
- filter.doChain( request, response );
- return;
- } else {
- redirect( forbiddenHintPage, request, response );
- return;
- }
- }
- }
基礎數據庫表
用戶信息表,保存用戶信息還有密碼等,有的系統會對密碼進行加密保存到數據庫,而不是以明文的形式保存到數據庫。
權限表,該表基本有這么幾個字段:標識、名稱、描述、指向 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 。
配置示例:
- <filter>
- <filter-name>metadmin/LoginFilter</filter-name>
- <filter-class>org.back.webFilter.LoginFilter</filter-class>
- <init-param>
- <param-name>loginPage</param-name>
- <param-value>/metadmin/demo/login.jsp</param-value>
- </init-param>
- <init-param>
- <param-name>uniqueFieldsParams</param-name>
- <param-value>loginName</param-value>
- </init-param>
- <init-param>
- <param-name>passwordParam</param-name>
- <param-value>password</param-value>
- </init-param>
- <!--init-param>
- <param-name>encryptMethod</param-name>
- <param-value>shahex</param-value>
- </init-param-->
- </filter>
- <filter>
- <filter-name>metadmin/UrlAclFilter</filter-name>
- <filter-class>org.back.webFilter.UrlAclFilter</filter-class>
- <init-param>
- <param-name>loginPage</param-name>
- <param-value>/metadmin/demo/login.jsp</param-value>
- </init-param>
- <init-param>
- <param-name>denyPage</param-name>
- <param-value>/metadmin/demo/noPrivilege.jsp</param-value>
- </init-param>
- </filter>
-
- <filter-mapping>
- <filter-name>metadmin/LoginFilter</filter-name>
- <url-pattern>/metadmin/demo/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>metadmin/UrlAclFilter</filter-name>
- <url-pattern>/metadmin/demo/*</url-pattern>
- </filter-mapping>
posted on 2009-06-16 15:39
細粒度權限管理 閱讀(3006)
評論(4) 編輯 收藏