为啥 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 Oauth2 SSO:使用 AuthorizationServer 授予的权限
为啥 Spring RestTemplate 在 Spring 中默认不是 Bean?