美文网首页
Shiro4-基于url拦截-用户授权实现

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

作者: 我相信你爱过gg | 来源:发表于2017-05-17 21:27 被阅读1632次

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

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

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

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

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

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

创建公开地址配置文件

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

login.action=退出

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

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

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

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

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

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<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
        //遍历公开 地址,如果是公开 地址则放行
        for(String open_url:open_urls){
            if(url.indexOf(open_url)>=0){
                //如果是公开 地址则放行
                return true;
            }
        }
        
        //从配置文件中获取公共访问地址
        List<String> 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<SysPermission> 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;
    }

配置授权拦截器

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

    <!--拦截器 -->
    <mvc:interceptors>

        <mvc:interceptor>
            <!-- 用户认证拦截 -->
            <mvc:mapping path="/**" />
            <bean class="cn.xxx.interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <!-- 授权拦截 -->
            <mvc:mapping path="/**" />
            <bean class="cn.xxx.interceptor.PermissionInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

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


相关文章

网友评论

      本文标题:Shiro4-基于url拦截-用户授权实现

      本文链接:https://www.haomeiwen.com/subject/gpbdxxtx.html