• 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的方法的访问权限,如果有就放行,如果没有就拦截。如下图所示:

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

     

  • 相关阅读:
    织梦开发——相关阅读likeart应用
    织梦标签教程
    织梦专题调用代码
    HIT 2543 Stone IV
    POJ 3680 Intervals
    HIT 2739 The Chinese Postman Problem
    POJ 1273 Drainage Ditches
    POJ 2455 Secret Milking Machine
    SPOJ 371 Boxes
    HIT 2715 Matrix3
  • 原文地址:https://www.cnblogs.com/shaojiang/p/10346067.html
Copyright © 2020-2023  润新知