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

Dav*_*der 9 java spring-security

似乎有两种不同的模式:

模式#1
GenericFilterBean不认证本身.由于所使用的大多数出的现成的过滤器:UsernamePasswordAuthenticationFilter,DigestAuthenticationFilter,等.

  • 请求进入过滤器
  • 过滤器创建一个Authenticationauthenticated=false
  • 过滤器将其传递给它直接引用的特定 AuthenticationProvider(有时通过AuthenticationManager)
  • 如果一切顺利,他们会创建一个类型Authentication并传回过滤器
  • filter将其放入上下文中

    在这种模式中,原始Authentication只是一个传递给AuthenticationProvider它的POJO - 它永远不会进入上下文.
    此外,过滤器通常也会直接引用特定的内容EntryPoint- 最后调用它.
    (我认为这种模式适合预身份验证过滤器?但Spring代码中没有那种一致性).

    模式#2
    单独注册AuthenticationProviders进行身份验证.正如大多数在线示例所使用的那样,但在开箱即用的过滤器中很少见到.

  • 请求进入过滤器
  • 过滤器创建一个Authenticationauthenticated=false
  • filter将其放入上下文中.
  • 过滤器的工作完成了
  • spring security现在贯穿所有已注册的 AuthenticationProviders
  • 其中一个拿起这个Authentication并尝试验证它
  • 如果一切顺利,他们会改变Authenticationauthenticated=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>
    
    Run Code Online (Sandbox Code Playgroud)

    问题:何时使用一种方法或另一种方法是否有任何逻辑?

    模式#2 感觉最好.但我认为无论哪种方式都有效,并且我不确定哪种方式正确/最佳/最安全/最具前瞻性/最不可能与其他过滤器/等冲突.

    如果上下文很重要,那就是Spring Security 3.2.5,它将用于基于令牌的身份验证,我们在授予访问权限之前验证对远程服务的令牌详细信息(取自请求标头).

  • Dav*_*der 0

    已经三年了,所以我认为结论是,没有正确或错误的方法!

    自 Acegi 以来,Spring Security 的本质并没有发生太大变化,而且它似乎是不同方法的混合体。

    最后,我选择了模式#1。我不喜欢模式#2 使用可变对象,这些对象神奇地从authentiated = false 变为true!

    模式 #1 允许我使用两个不可变对象(一个始终验证为 false,另一个始终验证为 true - 但仅在成功时添加),这实际上感觉更安全。