spring 安全过滤器应该直接调用身份验证提供程序吗?
Should spring security filters call authentication providers directly?
似乎有两种不同的模式:
模式 #1
GenericFilterBean
自己进行身份验证。大多数 out-of-the-box 过滤器使用:UsernamePasswordAuthenticationFilter
、DigestAuthenticationFilter
等。
请求进入过滤器
过滤器创建一个 Authentication
和 authenticated=false
过滤器将其传递给它直接引用的 specific AuthenticationProvider
(有时通过 AuthenticationManager
)
如果一切顺利,他们会创建一个 new 类型的 Authentication
并传回过滤器
过滤器将其放入上下文中
在此模式中,原始 Authentication
只不过是传递给 AuthenticationProvider
的 POJO - 它永远不会进入上下文。
此外,通常情况下,过滤器还直接引用特定的 EntryPoint
- 它在最后调用。
(我认为这种模式适合 pre-authentication 过滤器?但是 Spring 代码中没有这种一致性)。
模式 #2
单独注册AuthenticationProviders
做认证。正如大多数在线示例所使用的那样,但在 out-of-the-box 过滤器中很少见。
请求进入过滤器
过滤器创建一个 Authentication
和 authenticated=false
filter 将其放入上下文中。
过滤器的工作完成了
spring 安全性现在贯穿所有已注册 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-proof/最不可能与其他过滤器冲突的等等
如果上下文很重要,这是 Spring 安全 3.2.5,并且将用于 token-based 身份验证,我们在其中验证令牌详细信息(取自请求 header)授予访问权限之前的远程服务。
3年过去了,我觉得结论是没有对错之分!
自从 Acegi 以来,Spring 安全性的核心并没有太大变化,它似乎是不同方法的混合体。
最后,我选择了模式#1。我不喜欢模式 #2 使用的可变对象神奇地从 authenticated = false 变为 true!
模式 #1 允许我使用两个不可变对象(一个始终验证为假,另一个始终验证为真 - 但仅在成功时添加),这实际上感觉更安全。
似乎有两种不同的模式:
模式 #1
GenericFilterBean
自己进行身份验证。大多数 out-of-the-box 过滤器使用:UsernamePasswordAuthenticationFilter
、DigestAuthenticationFilter
等。
Authentication
和 authenticated=false
AuthenticationProvider
(有时通过 AuthenticationManager
)
Authentication
并传回过滤器
在此模式中,原始 Authentication
只不过是传递给 AuthenticationProvider
的 POJO - 它永远不会进入上下文。
此外,通常情况下,过滤器还直接引用特定的 EntryPoint
- 它在最后调用。
(我认为这种模式适合 pre-authentication 过滤器?但是 Spring 代码中没有这种一致性)。
模式 #2
单独注册AuthenticationProviders
做认证。正如大多数在线示例所使用的那样,但在 out-of-the-box 过滤器中很少见。
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-proof/最不可能与其他过滤器冲突的等等
如果上下文很重要,这是 Spring 安全 3.2.5,并且将用于 token-based 身份验证,我们在其中验证令牌详细信息(取自请求 header)授予访问权限之前的远程服务。
3年过去了,我觉得结论是没有对错之分!
自从 Acegi 以来,Spring 安全性的核心并没有太大变化,它似乎是不同方法的混合体。
最后,我选择了模式#1。我不喜欢模式 #2 使用的可变对象神奇地从 authenticated = false 变为 true!
模式 #1 允许我使用两个不可变对象(一个始终验证为假,另一个始终验证为真 - 但仅在成功时添加),这实际上感觉更安全。