有两种不同的模式:
模式 #1GenericFilterBean
自行进行身份验证。 大多数开箱即用的过滤器使用:UsernamePasswordAuthenticationFilter
、DigestAuthenticationFilter
等。
authenticated=false
的Authentication
AuthenticationProvider
(有时通过AuthenticationManager
(Authentication
并传递回过滤器在这种模式中,原始Authentication
只不过是传递给AuthenticationProvider
的 POJO - 它永远不会进入上下文。
此外,通常情况下,过滤器还直接引用特定EntryPoint
- 它在末尾调用。
(我认为这种模式适合预身份验证过滤器? 但是在 Spring 代码中没有这种一致性(。
模式 #2
单独注册AuthenticationProviders
进行身份验证。 正如大多数在线示例所使用的那样,但在开箱即用的过滤器中很少见。
authenticated=false
的Authentication
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 感觉最好。 但我认为无论哪种方式都有效,并且不确定哪种方式是正确的/最好/最安全/最面向未来/最不可能与其他过滤器冲突/等。
如果上下文很重要,这是 Spring Security 3.2.5,它将用于基于令牌的身份验证,我们在授予访问权限
之前根据远程服务验证令牌详细信息(取自请求标头(。
3年了,所以我认为结论是没有正确或错误的方法!
Spring Security的胆量自从Acegi以来没有太大变化,它似乎是不同方法的混合体。
最后,我选择了模式#1。 我不喜欢模式 #2 使用可变对象的事实,这些对象神奇地从身份验证 = false 变为 true!
模式 #1 允许我使用两个不可变的对象(一个总是经过身份验证的 false,另一个总是经过身份验证的 true - 但仅在成功时添加(,这实际上感觉更安全。