GenericFilterBean vs OncePerRequestFilter 何时使用每个?

2022-09-02 10:54:51

我已经找到了一些与此主题相关的问题,但我意识到它们都没有阐明这个主题。

显然,OncePerRequestFilter确保请求在过滤器链中只通过过滤器一次,但我并不完全清楚什么时候会发生相反的情况。

很高兴看到一些使用其中一种或另一种的方案。还有一个关于何时以及如何在筛选器链上多次应用筛选器的示例。

例如:

  1. 对于 JWT 筛选器,应使用哪种实现,为什么?
  2. 对于 CORS 筛选器,应使用哪种实现,为什么?等。

答案 1

用于状态的 javadocOncePerRequestFilter

从 Servlet 3.0 开始,过滤器可以作为在不同线程中发生的调度的一部分被调用。可以配置筛选器是否应参与异步调度。但是,在某些情况下,servlet 容器采用不同的默认配置。因此,子类可以重写该方法以静态声明(如果确实应该在两种类型的调度期间调用一次),以便提供线程初始化、日志记录、安全性等。此机制补充了,但不能取代使用分派器类型配置筛选器的需要。javax.servlet.DispatcherType REQUESTjavax.servlet.DispatcherType ASYNCweb.xmlshouldNotFilterAsyncDispatch()web.xml

因此,这是春季实施的一项额外的“安全”功能,以确保无论环境如何,一切都能正常工作。如果你看看扩展它的类,你会发现有很多;包括。不确定是否有弹簧过滤器不会扩展它,可能不是。CorsFilter


答案 2

我们希望,一旦请求到达您的项目,您应该对其进行一次身份验证和授权。然后,如果一切正常,则可以允许此请求以及来自此上下文的任何其他请求命中您的 API,而无需再次通过筛选器。OncePerRequestFilter 确保此身份验证过程只发生一次。如果我们不使用它,每当我们在内部向项目中的其他API发出请求时,相同的身份验证将再次发生,因为我们所有的API都具有相同的安全过滤器。

一个常见的用例是在Spring Security中,其中身份验证和访问控制功能通常作为位于主应用程序servlet前面的过滤器来实现。当使用请求分派器调度请求时,它必须再次通过过滤器链(或者可能是不同的过滤器链),然后才能到达要处理它的 servlet。问题在于,某些安全筛选器操作只应对请求执行一次。因此,需要 OncePerRequestFilter over GenericFilterBean。


推荐