为啥 Spring 的 `AuthenticationWebFilter` 有自己的匹配器来检查请求是不是需要身份验证?

Posted

技术标签:

【中文标题】为啥 Spring 的 `AuthenticationWebFilter` 有自己的匹配器来检查请求是不是需要身份验证?【英文标题】:Why does Spring's `AuthenticationWebFilter` have it's own matcher for checking if a request needs authentication?为什么 Spring 的 `AuthenticationWebFilter` 有自己的匹配器来检查请求是否需要身份验证? 【发布时间】:2021-09-10 21:10:59 【问题描述】:

正如标题所说; AuthenticationWebFilter 有自己的一组匹配器来确定请求是否需要身份验证。这似乎不符合 Spring Security 的做事方式。

如果在 spring 安全配置中将端点设置为 .permitAll(),它也必须在 AuthenticationWebFilter 中排除,为什么过滤器不让请求通过,让其余的 spring 安全处理它?

编辑:重新构建我的问题以回应 Steve Riesenberg 的answer:

为什么AuthenticationWebFilter,一个身份验证过滤器,控制对资源的访问?这不应该由授权过滤器处理吗?

编辑:我刚刚发现过滤器实际上不会在没有身份验证时阻止访问,只有在验证失败时才阻止访问,这是有道理的。

【问题讨论】:

【参考方案1】:

我认为您的问题的答案在于了解 Spring Security 中的过滤器顺序和用途。您的问题专门引用了AuthenticationWebFilter,它用于反应式应用程序。 Spring Security 文档有一个 comprehensive list of filters in order 用于 servlet 应用程序,但您可以参考 SecurityWebFiltersOrder 枚举以了解反应式应用程序中的类似排序。

在这两种情况下,您都可以看到“授权”(servlet 中的FilterSecurityInterceptor,反应式中的AuthorizationWebFilter)实际上是列表中的最后一个过滤器。因此,如果您在http.authorizeExchange() 中设置到.permitAll() 的路由,那么您就是在指示授权管理器允许该请求,假设它通过了过滤器链中的所有其他过滤器。通过将AuthenticationWebFilter 中的匹配器设置为相同的路由,您要求 that 过滤器尝试对该路由进行身份验证,这将终止处理并且永远不会到达授权步骤。只有经过授权的请求才会到达您的应用程序代码,但某些请求可以在您的应用程序需要处理它们之前(而不是)由过滤器链处理。

简而言之,在授权之前尝试/处理身份验证。

【讨论】:

正如我在编辑中询问的那样;为什么身份验证过滤器控制对资源的访问?这不应该是授权过滤器的工作吗?【参考方案2】:

我发现我的困惑是由于误解了 AuthenticationWebFilter 的工作原理。我的理解是它会阻止任何未成功通过身份验证的请求,但事实证明它只会阻止身份验证失败的请求。完全没有身份验证的请求会被允许通过。

这实际上是有道理的。

我没有仔细研究这个过滤器,因为我记得有一个类似的 servlet 过滤器以这种方式工作,AbstractAuthenticationFilter 或我认为的其他东西。我仍然很确定一个可以这样工作,我仍然想知道为什么,但我不确定我会通过自己回答这个问题来结束这个问题。如果将来出现,我可能会发布另一个问题。

感谢回答的人!

【讨论】:

以上是关于为啥 Spring 的 `AuthenticationWebFilter` 有自己的匹配器来检查请求是不是需要身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

单点登录系统使用Spring Security的权限功能

Spring Oauth2 SSO:使用 AuthorizationServer 授予的权限

为啥 Spring RestTemplate 在 Spring 中默认不是 Bean?

为啥 Spring 的 ApplicationContext.getBean 被认为不好?

spring为啥是单例模式

Spring 安全 @PreAuthorize NullPointerException。为啥?