使用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

相關文章
相關標籤/搜索