GenericFilterBean vs OncePerRequestFilter什么时候使用每个?

Bog*_*san 6 java spring servlets spring-mvc servlet-3.0

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

显然,OncePerRequestFilter确保请求在过滤器链中仅通过过滤器一次,但是当发生相反的情况时,我不清楚。

很高兴看到一些使用其中一个或另一个的方案。也是有关何时以及如何在过滤器链上多次应用过滤器的示例。

例如

  1. 对于JWT过滤器,应使用哪种实现方式,为什么?
  2. 对于CORS过滤器,应使用哪种实现方式,为什么?等等

小智 9

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

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


Kay*_*man 4

OncePerRequestFilter各州的 javadoc

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

因此,它是 Spring 中实现的附加“安全”功能,以确保无论环境如何,一切都可以正常工作。如果您查看扩展它的类,您会发现有很多;包括CorsFilter。不确定是否有 Spring 过滤器扩展它,可能不会。