使用Spring Interceptor实现URL访问校验

本文中介绍我在简单的实际应用中,针对登陆用户的访问权限问题的具体实现,总体设计以下图:spring

权限验证

图中请求进入Spring容器后会对用户的有效性、权限进行验证,只有验证都经过以后才能进入实际业务逻辑。spring-mvc

上图的实现使用Spring MVC的HandleInterceptor、HandlerInterceptorAdapter实现,下文中将一一介绍到。mvc

HandlerInterceptor接口须要实现类管理请求执行前、执行后、和请求处理完成后所须要执行的动做。代码以下:app

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest var1,HttpServletResponse var2, Object var3) throws Exception;

    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
  • preHandle:对HTTP请求进行预处理,返回true则请求继续,返回false则须要对Response进行响应
  • postHandle:在HTTP请求实际业务逻辑完成后(View渲染以前),处理须要作的动做
  • afterCompletion:在View渲染完成以后,处理须要的动做

若是操做都须要进行控制,能够直接继承该接口并一一实现其中的方法。但有些时候咱们并不须要实现这么多的操做,例如:如今我要对访问的路径进行校验,则我只须要实现preHandle方法就能够知足,这里要用到它的适配器HandlerInterceptorAdapter,代码以下:ide

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
    public HandlerInterceptorAdapter() {
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    }
}
  • afterConcurrentHandlingStarted:该适配器中还对当前拦截器开始执行后的动做进行了拦截处理,适用于在进行验证以前对HTTP请求作一些统一的处理

接着,咱们继承该适配器并重写其中的方法就能够达到咱们的目的了,在这里以个人权限检查程序片断为例,代码以下:post

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求中拿到token
        String account = request.getParameter(ACCOUNT_KEY);
        String token = request.getParameter(TOKEN_KEY);

        // 打印Token和请求地址
        LOGGER.info("Account------->{}", account);
        LOGGER.info("Token--------->{}", token);
        LOGGER.info("ReqUrl-------->{}", request.getRequestURI());
        // 任意验证属性为空->从新登陆
        if (StringUtils.isEmpty(account) || StringUtils.isEmpty(token)) {
            response.sendRedirect(request.getContextPath() + "/err/needLogin");
            return false;
        }
        // 验证用户有效性.
        boolean flag = validateAccount(request, account, token);
        if (!flag) {
            // 用户权限验证未经过->从新登陆
            response.sendRedirect(request.getContextPath() + "/err/needLogin");
            return false;
        }
        // 验证路径权限(AntPathMatcher实现)
        boolean authFlag = authPath(request, account);
        // 打印验证结果
        LOGGER.info("UserAuth----->{}", flag);
        LOGGER.info("PathAuth----->{}", authFlag);
        if (flag && authFlag) {
            return true;
        } else {
            // 未经过路径权限验证,跳转到错误URL
            response.sendRedirect(request.getContextPath() + "/err/notAllow");
        }
        return false;
    }

这里根据个人验证逻辑我只实现了preHandle方法,其中使用AntPathMatcher实现路径匹配的实现会在下一篇中详细介绍。实现类完成后须要配置生效,那么在spring的配置文件中,咱们能够这么写,代码以下:设计

<!--Spring 路径拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--匹配路径-->
            <mvc:mapping path="/**"/>
            <!--从匹配路径移除不须要匹配的路径-->
            <mvc:exclude-mapping path="/user/login"/>
            <mvc:exclude-mapping path="/user/secode"/>
            <mvc:exclude-mapping path="/user/passwd"/>
            <mvc:exclude-mapping path="/err/*"/>
            <mvc:exclude-mapping path="/news/**"/>
            <!--该拦截器的实现(上面咱们完成的类)-->
            <bean class="cn.creditease.app.util.PathInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

不要忘了引入Spring Schema:code

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

这样咱们就经过Spring的拦截器实现了URL访问权限校验。xml

相关文章
相关标签/搜索