天天看點

若依非分離版-第六十三章:過濾器Filter

作者:源碼解析

了解過濾器Filter

  • 過濾器: Filter, 是 Servlet 技術中最實用的技術。
  • 過濾器是處于用戶端和伺服器之間的一個過濾網,可以過濾掉一些不符合要求的請求
  • 常見場景:
  • Session 校驗
  • 判斷使用者權限
  • 不符合設定條件,則會被重定向特殊的位址或者設定的響應
  • 過濾敏感詞彙
  • 設定編碼
若依非分離版-第六十三章:過濾器Filter

Filter生命周期

(1) 初始化階段 Servlet 容器負責加載和執行個體化 Filter。容器啟動時,讀取 web.xml 或 @WebFilter 的配置資訊對所有的過濾器進行加載和執行個體化。 加載和執行個體化完成後,Servlet 容器調用 init() 方法初始化 Filter 執行個體。在 Filter 的生命周期内, init() 方法隻執行一次。

(2) 攔截和過濾階段 該階段是 Filter 生命周期中最重要的階段。當用戶端請求通路 Web 資源時,Servlet 容器會根據 web.xml 或 @WebFilter 的過濾規則進行檢查。當用戶端請求的 URL 與過濾器映射比對時,容器将該請求的 request 對象、response 對象以及 FilterChain 對象以參數的形式傳遞給 Filter 的 doFilter() 方法,并調用該方法對請求/響應進行攔截和過濾。

(3) 銷毀階段 Filter 對象建立後會駐留在記憶體中,直到容器關閉或應用被移除時銷毀。銷毀 Filter 對象之前,容器會先調用 destory() 方法,釋放過濾器占用的資源。在 Filter 的生命周期内,destory() 隻執行一次。

ruoyi過濾器配置

過濾器子產品目錄,放在ruoyi-framework

若依非分離版-第六十三章:過濾器Filter

代碼如下:

/**
 * Filter配置
 *
 * @author ruoyi
 */
@Configuration
@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public class FilterConfig
{
    @Value("${xss.excludes}")
    private String excludes;

    @Value("${xss.urlPatterns}")
    private String urlPatterns;

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean xssFilterRegistration()
    {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        registration.setFilter(new XssFilter());
        registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
        registration.setName("xssFilter");
        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
        Map<String, String> initParameters = new HashMap<String, String>();
        initParameters.put("excludes", excludes);
        registration.setInitParameters(initParameters);
        return registration;
    }
}           

通過在springboot的configuration中配置不同的FilterRegistrationBean執行個體,來注冊自定義過濾器。如上述代碼建立一個configuration類

如上述代碼第22行,registration.setFilter(new XssFilter());注冊過濾器XssFilter是一個防止xss攻擊的過濾器,其中XssFilter的實作類檔案存放在ruoyi-common。具體路徑如下:

若依非分離版-第六十三章:過濾器Filter

如上述代碼第23行,registration.addUrlPatterns:配置過濾的url,其中url的規則配置在application.yml檔案裡面詳細如下:

# 比對連結
urlPatterns: /system/*,/monitor/*,/tool/*           

如上述代碼第25-27行,配置排除url,這些url不做攔截,非攔截url也是配置在application.yml裡面

# 排除連結(多個用逗号分隔)
 excludes: /system/notice/*           

XssFilter拆解

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException
{
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;
    if (handleExcludeURL(req, resp))
    {
        chain.doFilter(request, response);
        return;
    }
    XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
    chain.doFilter(xssRequest, response);
}           

如上述代碼第5行,擷取request執行個體

如上述代碼第6行,擷取response執行個體

handleExcludeURL:判斷是不是排除過濾url,excludes: /system/notice/*

如果是排除裡面,則繼續執行chain.doFilter(request, response);

如上述代碼第12行,進行xss過濾處理,具體執行代碼如下:

@Override
public String[] getParameterValues(String name)
{
    String[] values = super.getParameterValues(name);
    if (values != null)
    {
        int length = values.length;
        String[] escapseValues = new String[length];
        for (int i = 0; i < length; i++)
        {
            // 防xss攻擊和過濾前後空格
            escapseValues[i] = EscapeUtil.clean(values[i]).trim();
        }
        return escapseValues;
    }
    return super.getParameterValues(name);
}           

未來計劃

1、ruoyi非分離版本拆解

2、ruoyi-vue-pro:講解工作流

3、ruoyi-vue-pro:支付子產品,電商子產品

4、基于ruoyi-vue-pro項目開發

5、JEECG低代碼開發平台

請關注我,本星球會持續推出更多的開源項目代碼解析,如有更好的意見請留言回複或者私信。