随笔-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 细粒度权限管理 阅读(2998) 评论(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  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: