暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

选择过滤器还是拦截器?

一十二章经 2021-06-18
1867

在日常业务开发中,我们会编写一些系统级别的配置代码,比如我们会自定义实现Filter接口的XssFilter,用于防止XSS攻击。或是实现Spring框架提供的HandlerInterceptor接口,定义自己的拦截器。那么问题就来了,为什么选择Servlet中的Filter防御Web攻击而不是采用Spring的拦截器呢?或者说这两者的身份可以互换吗?

Filter什么时候被调用

Filter是Servlet规范组件之一,Tomcat作为Servlet容器自然也支持Filter。下图是一个Http请求过来后,Tomcat的处理流程

其他的组件可以先不用理会,直接看红色框出的文字。可以看出,在执行真正的Servlet之前会先执行Filter的doFilter方法。XssFilter就是在这里过滤掉非法字符。然后才进入Servlet。

HandlerInterceptor什么时候被调用

当Http请求顺利通过Filter后就可以开始执行Servlet了,SpringMVC处理所有请求的Servlet叫做前端控制器(DispatcherServlet),下面是DispatcherServlet的处理流程,可以说是面试必考题了。

我们自定义的拦截器就是在这个范围内工作,拦截器中不同的方法工作地点是不一样的,如下代码

public class MyInterceptor implements HandlerInterceptor {
    /**
     * HandlerAdapter执行controller前执行此方法
     */

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor执行了----前preHandle");
        return true;
    }
    /**
     * 执行完Controller后,DispatcherServlet执行该方法
     */

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println();
    }
    /**
     * DispatcherServlet渲染完视图并响应给用户后,操作该方法,即完成响应后执行
     */

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor执行了----最后afterCompletion");

    }
}

上面自定义的拦截器有3个重要的方法preHandle、postHandle、afterCompletion,这三个方法的工作地点如下图所示

图中深红色标注的地方就是Spring拦截器工作的地方。

Filter和Interceptor可不可互换角色

通过上面我们已经知道了Filter和Interceptor作用的地方是不一样的,那么在开发中我们使用Filter的场景能用Interceptor替换吗,比如防止XSS攻击的FIlter,我们能用个什么XssInterceptor替换吗?

技术实现上是可以的,但是我认为这样会违背当初定义Filter、Interceptor的初衷。Interceptor是Spring这类上层框架提供的,我们知道Spring是业务开发好帮手,帮我们屏蔽了底层很多配置,提供Interceptor目的是执行业务代码前做一些业务接口上的增强,比如对接口性能监控,日志记录。不是用来做一些安全性校验的工具。

Filter是Servlet容器级别的组件,相比较Interceptor,它更先处理Http请求。而容器是要为Web应用提供一个安全、可靠的运行环境,因此Filter可以保证进入Servlet的请求都是安全可信的。下图是Tomcat提供的Filter过滤器

从名字也可以看出都是针对容器安全的,比如跨域过滤器设置字符集过滤器等等。

总结

Filter是容器级别,它能保证执行业务代码前将一些非法有安全隐患的请求过滤掉。Interceptor是业务开发框架SpringMVC提供一个组件,存在目的是在执行DispatcherServlet逻辑时加入一些增强性功能代码。回到我们开头的问题:

可以Filter替换掉Interceptor吗?不能,因为执行DispatcherServlet的时候已经执行完Filter了,用Filter替换Interceptor达不到Interceptor对接口功能增强的效果。

可以用Interceptor替换Filter吗?可以但极其不推荐,虽然在Interceptor也能拦截到请求并做处理,但个人认为Spring提供Interceptor只是想对业务接口增强而不是做安全校验。


参考:<Tomcat架构解析>

文章转载自一十二章经,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论