简体   繁体   中英

Should spring security filters call authentication providers directly?

There seem to be two different patterns:

Pattern #1
The GenericFilterBean does the authenticating itself. As used by most of the out-of-the-box filters: UsernamePasswordAuthenticationFilter , DigestAuthenticationFilter , etc.

  • request comes into filter
  • filter creates an Authentication with authenticated=false
  • filter passes that to a specific AuthenticationProvider that it references directly (sometimes via an AuthenticationManager )
  • if all goes well, they create a new type of Authentication and pass back to filter
  • filter puts that into the context

    In this pattern, the original Authentication is nothing more than a POJO to pass to the AuthenticationProvider - it never goes into the context.
    Also, more often than not, the filter also has a direct reference to a specific EntryPoint - which it calls at the end.
    (I thought this pattern would suit pre-authentication filters? But there isn't that consistency in the Spring code).

    Pattern #2
    Separately registered AuthenticationProviders do the authentication. 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 puts that into the context.
  • filter's job is done
  • spring security now runs through all the registered AuthenticationProviders
  • one of those picks up this Authentication and attempts to verify it
  • if all goes well, they mutate the Authentication to authenticated=true

    In this pattern, the filter doesn't directly call an AuthenticationProvider , or an EntryPoint . These are registered externally and apply to all filters. Typical example of Pattern #2 config:

     <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. 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.

  • It's been 3 years, so I think the conclusion is that there isn't a right or wrong way!

    The guts of Spring Security haven't changed much since it was Acegi, and it seems to be a mix of different approaches.

    In the end, I went with Pattern #1. I didn't like the fact that Pattern #2 used mutable objects that magically changed from authenticated = false to 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.

    The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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