似乎有两种不同的模式:
模式#1
GenericFilterBean
本身进行身份验证。大多数开箱即用的过滤器使用:UsernamePasswordAuthenticationFilter
, DigestAuthenticationFilter
, ETC。
Authentication
与 authenticated=false
AuthenticationProvider
它直接引用(有时通过 AuthenticationManager
)
Authentication
并传回过滤器
在此模式中,原始 Authentication
无非是一个POJO传递给AuthenticationProvider
- 它永远不会进入上下文。
此外,过滤器通常还直接引用特定的 EntryPoint
- 它在最后调用。
(我认为这种模式适合预身份验证过滤器?但 Spring 代码中没有这种一致性)。
模式#2
单独注册AuthenticationProviders
进行身份验证。正如大多数在线示例所使用的那样,但在开箱即用的过滤器中很少见到。
Authentication
与 authenticated=false
AuthenticationProviders
Authentication
并尝试验证它
Authentication
至authenticated=true
在此模式中,过滤器不会直接调用 AuthenticationProvider
,或 EntryPoint
。这些是在外部注册的并适用于所有过滤器。模式 #2 配置的典型示例:
<sec:http use-expressions="true" entry-point-ref="myCustomEntryPoint" pattern="/**">
<sec:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myCustomFilter" />
...
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider ref="myCustomAuthenticationProvider" />
</sec:authentication-manager>
问题:何时使用一种方法或另一种方法是否有任何逻辑?
模式#2感觉最好。但我认为任何一种方法都会起作用,并且我不确定哪种方法是正确的/最好的/最安全的/最面向 future 的/最不可能与其他过滤器发生冲突/等等。
如果上下文很重要,这是 Spring Security 3.2.5,并将用于基于 token 的身份验证,我们在授予访问权限之前根据远程服务验证 token 详细信息(从请求 header 获取)。
最佳答案
已经三年了,所以我认为结论是没有正确或错误的方法!
自 Acegi 以来,Spring Security 的本质并没有太大变化,而且它似乎是不同方法的混合。
最后,我选择了模式#1。我不喜欢模式#2 使用可变对象,这些对象神奇地从authentiated = false 变为true!
模式 #1 允许我使用两个不可变对象(immutable对象)(一个始终验证为 false,另一个始终验证为 true - 但仅在成功时添加),这实际上感觉更安全。
关于java - Spring安全过滤器应该直接调用身份验证提供者吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28899303/