Shiro4-基于url拦截-用户授权实现

在上一个笔记中我们实现了用户认证,那么接下来我们实现用户授权,看一下流程图.

Shiro4-基于url拦截-用户授权实现_第1张图片

这个流程图就是上一个笔记中的图, 我截取的部分就是用户授权的流程

在流程图中我们看到有一个授权过滤器拦截获取访问URL,所以我们就需要创建这个拦截器,然后在拦截器中,进行下面流程操作.

我们可以看到有一个URL是否公开地址这个与我们上一个笔记中的公开地址是不一样的.

这个配置文件的所用是,让授权过滤器不对配置文件中的URL分配访问权限,可以允许直接访问.

可能有人会想在做用户认证的时候有一个公开地址,用户授权的时候也有一个公开地址,这两个公开地址不能使用同一个吗?
答:用户认证时候的那个公开地址,就是我们没有用户认证通过就能访问的地址,比如: 系统登录的URL.
而这个用户授权的公开地址是 我们已经通过用户认证了,进入后台,但是由于不同角色登录系统后有不同的权限,所以我们需要做一些限制,哪些权限能访问哪些URL地址.而所有权限都能访问的地址,我们就将这些地址放到公开URL配置文件中.

创建公开地址配置文件

我们创建一个名为commonURL.properties的文件来存放我们的URL公开地址.
我们在这个文件中配置两条数据

login.action=退出

如果用户访问的URL在公共访问地址中那么就可以直接访问,如果不在就会判断用户访问的这个URL在不在他的权限中,如果在那么可以访问,如果不在就提示无权操作.

但是这里要注意, 我们的权限是存在数据库中,而授权过滤器每次都要拦截用户访问的URL进行判断,那么就意味着我们每次都要操作数据库,但是如果我们每次都去操作数据库这也就意味着会降低系统性能.

所以我们的解决方案就是,在用户认证通过后将权限取出,放到session中或缓存中.

获取用户权限范围的URL与用户菜单

思路: 在用户认证通过后,根据用户id从数据库获取用户权限范围的url,然后将url的集合存储在session中.

Shiro4-基于url拦截-用户授权实现_第2张图片

SQL语句

    SELECT 
      * 
    FROM
      sys_permission 
    WHERE TYPE = #{type}
      AND id IN 
      (SELECT 
        sys_permission_id 
      FROM
        sys_role_permission 
      WHERE sys_role_id IN 
        (SELECT 
          sys_role_id 
        FROM
          sys_user_role 
        WHERE sys_user_id = #{id}))

参数 type: 如果要查询权限就写permission 如果要查询菜单就写menu
参数 id: 用户id

然后在service中查询出来,将菜单和url放入你创建的ActiveUser对象中,再将这个对象放入session中.

上面的这些操作就是取出我们要的数据,并且放到session中了,接下来就是判断了.

最终代码

    //在执行handler之前来执行的
    //用于用户认证校验、用户权限校验
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        
        //得到请求的url
        String url = request.getRequestURI();
        
        //判断是否是公开 地址
        //实际开发中需要公开 地址配置在配置文件中
        //从配置中取逆名访问url
        
        List open_urls = ResourcesUtil.gekeyList("anonymousURL");
        //遍历公开 地址,如果是公开 地址则放行
        for(String open_url:open_urls){
            if(url.indexOf(open_url)>=0){
                //如果是公开 地址则放行
                return true;
            }
        }
        
        //从配置文件中获取公共访问地址
        List common_urls = ResourcesUtil.gekeyList("commonURL");
        //遍历公用 地址,如果是公用 地址则放行
        for(String common_url:common_urls){
            if(url.indexOf(common_url)>=0){
                //如果是公开 地址则放行
                return true;
            }
        }
        
        //获取session
        HttpSession session = request.getSession();
        ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
        //从session中取权限范围的url
        List permissions = activeUser.getPermissions();
        for(SysPermission sysPermission:permissions){
            //权限的url
            String permission_url = sysPermission.getUrl();
            if(url.indexOf(permission_url)>=0){
                //如果是权限的url 地址则放行
                return true;
            }
        }
        
        //执行到这里拦截,跳转到无权访问的提示页面
        request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
        
        //如果返回false表示拦截不继续执行handler,如果返回true表示放行
        return false;
    }

配置授权拦截器

注意:将授权连接器配置在用户认证拦截器的下边.

    
    

        
            
            
            
        
        
            
            
            
        
    

这样就做完了,但是这种方式有好处也有坏处
好处:实现起来比较简单,不依赖框架,使用web提供的filter就可以实现.
坏处:需要将所有的url全部配置起来(放入数据库和公共文件中),这样做有些繁琐,不容易维护.


Shiro4-基于url拦截-用户授权实现_第3张图片

你可能感兴趣的:(Shiro4-基于url拦截-用户授权实现)