springmvc实现权限控制

大体思想:

当系统启动的时候会将所有权限信息加入到Map集合,URL作为key,有此权限访问该URL的角色作为value;然后具体某个用户登录的时候会首先获取其对应的角色,存到session中;当该用户访问某个具体的URL时会进行角色判断其是否由此权限进行访问。

实现过程:

1.定义拦截器(springmvc-servlet.xml)

<!-- 定义拦截器,判断登陆 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <mvc:exclude-mapping path="/**/*.js" />
        <bean class="com.thank.filter.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

2.定义一个类在启动的时候加载所有功能对应的权限

public class FuncCache{
    public static Map<String, Object> FUNCTION_MAP = new HashMap<>();
    static{
        // 如1-交易所  2-机构管理员 24-表示仓库机构有权限
        FUNCTION_MAP.put("/warehouse/init", ",1,24,29");
    }
}

3.定义拦截方法继承HandlerInterceptorAdapter,在Controller之前执行。该类在springmvc-servlet配置文件配置了,当有请求过来的时候会进行拦截。

public class LogingInterceptor extends HandlerInterceptorAdapter{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response
        , Object handler) throws Exception{
        String website = request.getScheme() + "://" + request.getServerName() 
            + ":" + request.getServerPort() + request.getContextPath();
        String referer = request.getHeader("Referer");
        if(referer != null && !referer.startsWith(website)){ // 不能通过别的站点链接过来
            return false;
        }
        String servletPath = request.getRequestURI();
        if(servletPath.endsWith(request.getContextPath()+"/") || 
            servletPath.endsWith(request.getContextPath())){
            return true;
        }
        // 浏览器直接打开login.html,非ajax请求也跳到登陆页面
        if(servletPath.contains("/login.html") && (request.getHeader("x-requested-with") == null
            || !request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest"))){
            request.getRequestDispatcher("./").forward(request, response);
            return false;
        } 
        // 不需要登陆
        if((servletPath.contains("/login") || servletPath.contains("/loginIn") ||
            servletPath.contains("/loginOut") || servletPath.contains("/externalCall"))
            && (!servletPath.contains("/operation/login"))){
            return true;
         } 
 
        HttpSession session = request.getSession(true);
        LoginRsp rsp = (LoginRsp) session.getAttribute(Constants.SESSION_LOGIN_KEY);
        if(rsp == null){
            // 如果是ajax请求到ajax:error处理
            if(request.getHeader("x-requested-with") != null
                && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                PrintWriter pw = response.getWriter();
                pw.write("losesession");
                pw.flush();
                pw.close();
                return false;
            }
            // 如果是正常请求,跳转页面
            response.sendRedirect(website);
            return false;
        }else{
            if(rsp.getCode() != Constants.loginSuccess && rsp.getCode() != Constants.loginChange){
                // 登陆状态不为成功 一律跳转登入页面
                request.getRequestDispatcher("./").forward(request, response);
                return false;
            }
            // 请求判断url,机构角色权限,没有权限跳到common.jsp
            if(!checkFuncAuth(rsp, request.getServletPath())){
                request.getRequestDispatcher("/blank").forward(request, response);
                return false;
            }
            return true;
        }
    }

    private boolean checkFuncAuth(LoginRsp rsp, String reqPath){
        int reletype = rsp.getUser().getReletype();
        String rlts = (String)FuncCache.FUNCTION_MAP.get(reqPath);
        if(rlts == null){ // 如果不在过滤列表就不过滤
            return true;        
        }
        // 子机构或交易所
        if(reletype == SysContants.SYS_TYPE_CLIENT){ // 机构
            if(rlts.contains("," + reletype + ","))    return true;
            String roles = rsp.getOrgztype(); // 拿到机构角色
            if(roles == null)
                return false; // 建了机构还未配机构角色
            String [] roletypes = roles.split(",");
            for(String roletype : roletypes){
                if(rlts.contains("," + reletype + roletype + ",")){
                    return true;
                }
            }
            return false;
        }else{
            return rlts.contains("," + reletype + ",");
        }
    }

    // preHandle返回true,在Controller方法调用之后,并且在DispathcherServlet进行视图渲染之前执行
    @Override
    public void postHandle(HttpServletRequest request, xxxxx

    // preHandler返回true,在DispatcherServlet视图渲染之后执行
    @Override
    public void afterCompletion(xxxxx
}

4.涉及到的标有

1)系统管理员表(SystemManager):

自增AutoID   用户类型(交易所管理员、机构管理员)ReleType   登录账号   用户姓名   密码   所属机构    ...

2)角色表(SystemManagerRole)

自增AutoID   角色名称   所属机构   角色类型(管理端、交易端)Roletype   ...

3)角色用户表(RoleUser)

用户ManagerID   角色RoleID   角色类型

4)功能菜单表(FuncMenuList)

资源代码   资源名   级别   菜单类型   上级资源代码   Url   排序   菜单图标

5)角色菜单表(RoleFuncMenu)

角色权限RoleID   菜单代码ResourceCode

附:亦可以参考此博客https://blog.csdn.net/u011277123/article/details/68940939

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值