zoukankan      html  css  js  c++  java
  • JavaEE权限管理系统的搭建(六)--------使用拦截器实现菜单URL的跳转权限验证和页面的三级菜单权限按钮显示

    本小结讲解,点击菜单进行页面跳转,看下图,点击管理员列表后会被认证拦截器首先拦截,验证用户是否登录,如果登录就放行,紧接着会被权限验证拦截器再次拦截,拦截的时候,会根据URL地址上找到对应的方法,然后查询方法上标注的自定义权限注解,紧接着根据当前登录用户查询出所有权限列表,然后进行验证,如果包含对应注解中的权限代码,就放行,否则提示或者跳转到404.

     /**
         * 进入管理用户列表页面
         * @return
         */
        @AccessPermissionsInfo("admin:list")
        @RequestMapping(value = "/admin-user-list.action",method = RequestMethod.GET)
        public String adminUserListPage(HttpSession session,Model model){
    
            //获取session用户是否存在
            AdminUser adminUser = (AdminUser)session.getAttribute("adminUser");
            if(adminUser!=null){
                //根据用户名查询出该用户所有拥有的权限集合,
                //这个权限集合查询出来了的集合是一个String集合,查询出来只有一列数据permission.code
                List<String> permissions =
                        permissionService.findAllPermissionByLoginName(adminUser.getLoginName());
                model.addAttribute("permissions",permissions);
            }
            return "admin-user-list";
    
    
        }

    拦截器的拦截过程如下图:

    AuthorizationInterceptor类:

    package com.supin51.interceptor;
    
    import com.supin51.domain.AdminUser;
    import com.supin51.service.PermissionService;
    import com.supin51.utils.AccessPermissionsInfo;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.List;
    
    /**
     * @Author:ShaoJiang
     * @description: 权限认证拦截器
     * @Date: created in 下午1:43 2019/1/21
     * @Modified By:
     */
    public class AuthorizationInterceptor implements HandlerInterceptor {
    
        private static final Log logger = LogFactory.getLog(AuthorizationInterceptor.class);
    
    
        @Autowired
        private PermissionService permissionService;
    
        /*
          * return true 才会继续执行下列两个方法(请求继续),否则整个请求结束
          * 该方法主要进行拦截处理,该方法在Controller处理之前调用,
          * */
        @Override
        public boolean preHandle(HttpServletRequest request,
                                 HttpServletResponse response, Object handler) throws Exception {
    
            //获取请求的路径进行判断
            String servletUrl = request.getServletPath();
            logger.info("权限认证拦截器:preHandle-------->"+servletUrl);
    
            //是否授权,默认为未授权
            boolean isAuthorize = false;
    
    
            //如果方法上有权限注释
            if(handler.getClass().isAssignableFrom(HandlerMethod.class))
            {
                AccessPermissionsInfo permissionsInfo =
                        ((HandlerMethod)handler).getMethodAnnotation(AccessPermissionsInfo.class);
    
                if (permissionsInfo==null||permissionsInfo.value()=="")
                {
                    isAuthorize = true;
                    logger.info("权限认证拦截器:preHandle-------->不需要权限,可以访问");
                }else
                {
                    String permission = permissionsInfo.value().toString();
                    logger.info("权限认证拦截器:preHandle-------->需要权限:"+permission+"才可以访问");
                    //获取session中的用户信息
                    AdminUser adminUser = (AdminUser)request.getSession().getAttribute("adminUser");
                    //如果用户已登录,放行,否则拦截
                    if(adminUser!=null){
                        //根据用户名查询出该用户所有拥有的权限集合
                        List<String> permissions =
                                permissionService.findAllPermissionByLoginName(adminUser.getLoginName());
                        //判断权限集合中的URL字段是否包含请求的路径,如果包含就放行,否则引导至提示(权限不足,请联系管理员)页面
    
                        for(String s:permissions)
                        {
                            if(permission.contains(s)){
                                isAuthorize = true;
                                logger.info("权限认证拦截器:preHandle-------->当前登录用户:"+adminUser.getLoginName()+""+permission+"访问权限,验证通过");
                                break;
                            }
                        }
                    }
                }
    
            }
    
    
            if(!isAuthorize){
                logger.info("权限认证拦截器:preHandle-------->权限不足或者无法访问该资源");
                //转发至404页面
                request.getRequestDispatcher("/404").forward(request,response);
            }
    
            return isAuthorize;
    
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            logger.info("权限认证拦截器:postHandle-------->");
        }
    
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            logger.info("权限认证拦截器:afterCompletion-------->");
        }
    }

    自定义注解类

    package com.supin51.utils;
    
    import java.lang.annotation.*;
    
    /**
     * @Author:ShaoJiang
     * @description:自定义权限注解,用于注解在controller方法上,在拦截器中拦截用户是否有权限访问
     * @Date: created in 下午8:44 2019/1/22
     * @Modified By:
     */
    @Inherited
    @Target(ElementType.METHOD)//用于方法上的注解
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AccessPermissionsInfo {
    
        /**
         * 权限名称值
         * @return 权限名称
         */
        String value() default "";
    
    
    }

    持久层PermissionMapper.xml

    <!--这个方法获取的权限返回列只有一个code字段,主要用在了拦截器和页面上的按钮权限控制显示-->
        <!--对应PermissionDao接口中的findAllPermissionByLoginName方法-->
        <select id="findAllPermissionByLoginName" parameterType="string" resultType="string" >
            SELECT tp.code
            FROM t_admin ta
            LEFT JOIN t_admin_role tar
                 ON tar.adminId = ta.id
            LEFT JOIN t_role tr
                 ON tar.roleId = tr.id
            LEFT JOIN t_role_permission trp
                 ON trp.roleId = tr.id
            LEFT JOIN t_permission tp
                 ON tp.id = trp.permissionId
            WHERE ta.loginName = #{loginName}
                 AND tp.url IS NOT NULL
        </select>

    页面成功跳转显示以后,在页面通过了EL表达式和jstl标签控制三级菜单权限按钮的显示,如下图:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>



    <c:set var="permiss" value="${permissions}"/> <c:if test="${fn:contains(permiss,'admin:add')}" > <a href="javascript:;" onclick="admin_add('添加管理员','/admin/admin-user-add.action',null,'800px','500px')" class="btn btn-primary radius"> <i class="Hui-iconfont Hui-iconfont-user-add"></i> 添加</a> </c:if> <c:if test="${fn:contains(permiss,'admin:edit')}" > <a href="javascript:;" onclick="admin_edit('编辑管理员','/admin/admin-user-edit.action',null,'800px','500px')" class="btn btn-primary radius"> <i class="Hui-iconfont Hui-iconfont-edit"></i> 编辑</a> </c:if> <c:if test="${fn:contains(permiss,'admin:delete')}" > <a href="javascript:;" onclick="deleteAll()" class="btn btn-danger radius"> <i class="Hui-iconfont Hui-iconfont-del"></i> 删除</a> </c:if> <c:if test="${fn:contains(permiss,'admin:enable')}" > <a href="javascript:;" onclick="admin_start()" class="btn btn-success radius"> <i class="Hui-iconfont Hui-iconfont-jiesuo"></i> 解锁</a> </c:if> <c:if test="${fn:contains(permiss,'admin:disable')}" > <a href="javascript:;" onclick="admin_stop()" class="btn btn-danger radius"> <i class="Hui-iconfont Hui-iconfont-suoding "></i> 冻结</a> </c:if> <c:if test="${fn:contains(permiss,'admin:pwdReset')}" > <a href="javascript:;" onclick="admin_user_password_reset()" class="btn btn-danger radius"> <i class="Hui-iconfont Hui-iconfont-zhongzuo"></i> 重置密码</a> </c:if>

    使用tom账户测试权限拦截,可以看到tom的角色在未分组里,而未分组里面什么权限也没有,当tom登录后,也看不到任何的菜单,如果强行通过网址URL进行方法,认证拦截器首先会进行验证是否登录,如果登录就放行到下一个拦截器,权限拦截器开始验证用户tom是否具有这个访问url的方法的访问权限,如果有就放行,如果没有就拦截。如下图所示:

    到本小节结束,登录认证和权限验证已经全部完成。下一小节将讲解添加用户(添加用户的同时也要给用户分配角色,然后插入的到用户和角色的中间表)和添加角色(添加角色的同时也要给角色分配权限,然后插入到角色和权限的中间表)。

     

  • 相关阅读:
    8月3日云栖精选夜读:LSF-SCNN:一种基于CNN的短文本表达模型及相似度计算的全新优化模型
    linux(centos)下安装PHP的PDO扩展
    Linux中find常见用法示例
    01 编译原理概述
    20145221 《信息安全系统设计基础》第5周学习总结
    20145221 《信息安全系统设计基础》第4周学习总结
    爱春秋之戏说春秋 Writeup
    20145221 《信息安全系统设计基础》第3周学习总结
    20145221 《信息安全系统设计基础》第2周学习总结
    20145221 《信息安全系统设计基础》第1周学习总结
  • 原文地址:https://www.cnblogs.com/shaojiang/p/10346067.html
Copyright © 2011-2022 走看看