简体   繁体   English

spring安全过滤器应该直接调用身份验证提

[英]Should spring security filters call authentication providers directly?

There seem to be two different patterns: 似乎有两种不同的模式:

Pattern #1 模式#1
The GenericFilterBean does the authenticating itself. GenericFilterBean自己进行身份验证。 As used by most of the out-of-the-box filters: UsernamePasswordAuthenticationFilter , DigestAuthenticationFilter , etc. 正如大多数开箱即用的过滤器所使用的: UsernamePasswordAuthenticationFilterDigestAuthenticationFilter等。

  • request comes into filter 请求进入过滤器
  • filter creates an Authentication with authenticated=false filter使用authenticated=false创建Authentication authenticated=false
  • filter passes that to a specific AuthenticationProvider that it references directly (sometimes via an AuthenticationManager ) filter将其传递给它直接引用的特定 AuthenticationProvider (有时通过AuthenticationManager
  • if all goes well, they create a new type of Authentication and pass back to filter 如果一切顺利,他们会创建一种Authentication并传回过滤器
  • filter puts that into the context filter将其放入上下文中

    In this pattern, the original Authentication is nothing more than a POJO to pass to the AuthenticationProvider - it never goes into the context. 在这种模式中,原始Authentication只不过是传递给AuthenticationProvider的POJO - 它永远不会进入上下文。
    Also, more often than not, the filter also has a direct reference to a specific EntryPoint - which it calls at the end. 此外,过滤器通常也直接引用特定的EntryPoint - 它最后调用它。
    (I thought this pattern would suit pre-authentication filters? But there isn't that consistency in the Spring code). (我认为这种模式适合预身份验证过滤器?但Spring代码中没有那种一致性)。

    Pattern #2 模式#2
    Separately registered AuthenticationProviders do the authentication. 单独注册的AuthenticationProviders进行身份验证。 As used by most examples online, but rarely seen in the out-of-the-box filters. 正如大多数在线示例所使用的那样,但在开箱即用的过滤器中很少见到。

  • request comes into filter 请求进入过滤器
  • filter creates an Authentication with authenticated=false filter使用authenticated=false创建Authentication authenticated=false
  • filter puts that into the context. filter将其放入上下文中。
  • filter's job is done 过滤器的工作完成了
  • spring security now runs through all the registered AuthenticationProviders spring security现在运行所有已注册的AuthenticationProviders
  • one of those picks up this Authentication and attempts to verify it 其中一个接受此Authentication并尝试验证它
  • if all goes well, they mutate the Authentication to authenticated=true 如果一切顺利,他们会将Authentication变为authenticated=true

    In this pattern, the filter doesn't directly call an AuthenticationProvider , or an EntryPoint . 在此模式中,筛选器不直接调用AuthenticationProviderEntryPoint These are registered externally and apply to all filters. 这些是在外部注册的,适用于所有过滤器。 Typical example of Pattern #2 config: 模式#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> 

    Question: Is there any logic for when to use one approach or the other? 问题: 何时使用一种方法或另一种方法是否有任何逻辑?

    Pattern #2 feels best. 模式#2 感觉最好。 But I think either way will work, and am unsure which is correct / best / most secure / most future-proof / least likely to conflict with other filters / etc. 但我认为无论哪种方式都有效,并且我不确定哪种方式正确/最佳/最安全/最具前瞻性/最不可能与其他过滤器等冲突。

    If the context matters, this is Spring Security 3.2.5, and will be for token-based authentication where we verify token details (taken from the request header) against a remote service before granting access. 如果上下文很重要,那就是Spring Security 3.2.5,它将用于基于令牌的身份验证,我们在授予访问权限之前验证对远程服务的令牌详细信息(取自请求标头)。

  • It's been 3 years, so I think the conclusion is that there isn't a right or wrong way! 已经3年了,所以我认为结论是没有正确或错误的方式!

    The guts of Spring Security haven't changed much since it was Acegi, and it seems to be a mix of different approaches. Spring Security的内容并没有太大变化,因为它是Acegi,它似乎是不同方法的混合。

    In the end, I went with Pattern #1. 最后,我选择了模式#1。 I didn't like the fact that Pattern #2 used mutable objects that magically changed from authenticated = false to true! 我不喜欢这样的事实:Pattern#2使用了从authenticated = false到true的神奇变化的可变对象!

    Pattern #1 allowed me to use two immutable objects (one always authenticated false, the other always authenticated true - but only added on success), which actually felt safer. 模式#1允许我使用两个不可变对象(一个始终验证为false,另一个始终验证为true - 但仅在成功时添加),这实际上感觉更安全。

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM