• 权限控制方案之——基于URL拦截


    概述:

             在系统开发过程中需要考虑的一个重要的问题就是权限问题,权限问题也是安全问题的一个范畴,我们要求在用户登录系统之后,要控制用户可以访问的系统资源,使得用户只可以访问到系统事先分配好的资源;这里的资源可以是一个URL地址,也可以是页面上的菜单和按钮等。对于实现权限的控制有多种方案,这里说明一下通过URL拦截的方式进行权限控制的实现方案。

    基本流程:

             对于权限的控制可以分为两个步骤:认证和授权。

             认证:即用户登录系统的时候对用户的身份信息进行判别。

             授权:即在用户登录成功后为用户分配用户可以访问的资源。

             流程图:根据用户的认证和授权过程抽象出如下流程图

             

    通用模型:

             根据我们对权限控制的要求,我们可以抽取出如下数据模型:

             主体:用户,程序等,包括账号和密码等属性

             资源:URL,菜单,按钮等

             角色:为了方便资源和主体之间的关系管理,我们一般会在它们之间抽取出一个角色实体,一个角色就是一类主体,通过角色可以实现对主体的分组管理,这样可以更加方便的对主体和其所对应的资源进行管理(扩张和修改)。

             模型结构如下图所示:

             

    实现过程:

             1、定义用户身份和基本操作:

             这里我们创建一个用户的身份实体ActiveUser,用来存放用户的身份信息,在用户登录成功后将该身份信息存放到session当中,

    [java] view plain copy
     
    1. //用户登陆请求  
    2. @RequestMapping("/loginsubmit")  
    3. public String loginsubmit(HttpSession session,String usercode,String password,String randomcode) throws Exception{  
    4.   
    5.     //校验验证码  
    6.     //从session获取正确验证码  
    7.     String validateCode = (String)session.getAttribute("validateCode");  
    8.     if(!randomcode.equals(validateCode)){  
    9.         //抛出异常:验证码错误  
    10.         throw new CustomException("验证码 错误 !");  
    11.     }  
    12.     //用户身份认证  
    13.     ActiveUser activeUser = sysService.authenticat(usercode, password);  
    14.       
    15.     //登录成功将用户信息记录到session  
    16.     session.setAttribute("activeUser", activeUser);  
    17.     //跳转到首页  
    18.     return "redirect:first.action";  
    19. }  
    20. //退出请求  
    21. @RequestMapping("/logout")  
    22. public String logout(HttpSession httpSession) throws Exception{  
    23.     //清空session  
    24.     httpSession.invalidate();  
    25.     return "redirect:first.action";  
    26. }  

             2、公开访问地址配置:

             对于不需要用户认证就可以访问的地址信息进行配置,这里我们可以单独写一个配置文件进行配置,后边读取判断。

    [plain] view plain copy
     
    1. #公开访问地址  
    2. login.action=登录页面  
    3. loginsubmit.action=登录请求  

             3、公共访问地址配置:

             对于只要用户认证通过就可以访问的地址信息进行配置,这里我们同样也是通过一个配置文件进行配置,后边通过读取判断。

    [plain] view plain copy
     
    1. #公共访问地址  
    2. first.action=首页  
    3. logout.action=退出  

             4、认证拦截器:

             通过认证拦截器对用户身份信息进行判断。

    [java] view plain copy
     
    1. public class LoginInterceptor implements HandlerInterceptor {  
    2.     @Override  
    3.     public boolean preHandle(HttpServletRequest request,  
    4.             HttpServletResponse response, Object handler) throws Exception {  
    5.   
    6.         // 校验是否是公开资源地址  
    7.         List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");  
    8.   
    9.         // 用户访问的url  
    10.         String url = request.getRequestURI();  
    11.         for (String open_url : open_urls) {  
    12.             if (url.indexOf(open_url) >= 0) {  
    13.                 // 如果访问的是公开 地址则放行  
    14.                 return true;  
    15.             }  
    16.         }  
    17.   
    18.         // 用户是否登录成功  
    19.         HttpSession session = request.getSession();  
    20.         ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");  
    21.         if (activeUser != null) {  
    22.             // 用户已经登陆认证,放行  
    23.             return true;  
    24.         }  
    25.         // 否则跳转到登陆页面  
    26.         request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,  
    27.                 response);  
    28.         return false;  
    29.     }  
    30.   
    31.     @Override  
    32.     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
    33.             Object arg2, ModelAndView arg3) throws Exception {  
    34.     }  
    35.   
    36.     @Override  
    37.     public void afterCompletion(HttpServletRequest arg0,  
    38.             HttpServletResponse arg1, Object arg2, Exception arg3)  
    39.             throws Exception {  
    40.     }  
    41. }  

             5、授权拦截器

             通过授权拦截器,判断用户是否具有访问资源的权限。

    [java] view plain copy
     
    1. public class PermissionInterceptor implements HandlerInterceptor {  
    2.     @Override  
    3.     public boolean preHandle(HttpServletRequest request,  
    4.             HttpServletResponse response, Object handler) throws Exception {  
    5.   
    6.         String url = request.getRequestURI();  
    7.   
    8.         // 校验是否是公开资源地址  
    9.         List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");  
    10.   
    11.         for (String open_url : open_urls) {  
    12.             if (url.indexOf(open_url) >= 0) {  
    13.                 // 公开地址放行  
    14.                 return true;  
    15.             }  
    16.         }  
    17.         //判断是否是公共访问地址  
    18.         List<String> common_urls = ResourcesUtil.gekeyList("commonURL");  
    19.   
    20.         for (String common_url : common_urls) {  
    21.             if (url.indexOf(common_url) >= 0) {  
    22.                 //公共地址放行  
    23.                 return true;  
    24.             }  
    25.         }  
    26.   
    27.         HttpSession session = request.getSession();  
    28.         ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");  
    29.         // 获取用户权限列表  
    30.         List<SysPermission> permission_list = activeUser.getPermissions();  
    31.         // 校验用户访问地址是否在用户权限范围内  
    32.         for (SysPermission sysPermission : permission_list) {  
    33.             String permission_url = sysPermission.getUrl();  
    34.             if (url.contains(permission_url)) {  
    35.                 return true;  
    36.             }  
    37.         }  
    38.         // 跳转到拒绝访问的页面  
    39.         request.getRequestDispatcher("/refuse.jsp").forward(  
    40.                 request, response);  
    41.         return false;  
    42.     }  
    43.   
    44.     @Override  
    45.     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
    46.             Object arg2, ModelAndView arg3) throws Exception {  
    47.   
    48.     }  
    49.   
    50.     @Override  
    51.     public void afterCompletion(HttpServletRequest arg0,  
    52.             HttpServletResponse arg1, Object arg2, Exception arg3)  
    53.             throws Exception {  
    54.     }  
    55. }  

             6、配置拦截器

             将拦截器配置起来,使其工作。

    [html] view plain copy
     
    1. <!-- 拦截器 -->  
    2. <mvc:interceptors>  
    3.     <!-- 多个拦截器,顺序执行 -->  
    4.     <!-- 认证拦截器 -->  
    5.     <mvc:interceptor>  
    6.         <mvc:mapping path="/**" />  
    7.         <bean class="cn.itcast.ssm.controller.interceptor.LoginInterceptor"></bean>  
    8.     </mvc:interceptor>  
    9.     <!-- 授权拦截器 -->  
    10.     <mvc:interceptor>  
    11.         <mvc:mapping path="/**" />  
    12.         <bean class="cn.itcast.ssm.controller.interceptor.PermissionInterceptor"></bean>  
    13.     </mvc:interceptor>  
    14. </mvc:interceptors>  

    总结

             这里主要是通过两个拦截器实现了认证和授权,其优点是可以不必依赖于框架实现,对于拦截器我们也可以通过web提供的filter实现;缺点在于对于系统配置很多的URL,或者在系统初始化时将URL设置到数据库中,再有就是对于访问地址的变动要同时改变配置,维护相对不易。

  • 相关阅读:
    OCS 2007 R2下载资源整理
    Windows Server 2012 R2 WSUS 4.0 加速
    JavaScript入门(三)
    JavaScript入门(一)
    JavaScript入门(二)
    CSS基础
    古董代码
    自我介绍
    Android Activity的加载的模式
    Android 数字签名
  • 原文地址:https://www.cnblogs.com/DreamRecorder/p/9081785.html
Copyright © 2020-2023  润新知