SpringSecurity架构

225 阅读1分钟

Servlet 认证架构

总体架构:

AuthenTicationFilter

AuthenticationFilter:用于获取请求中的信息,并创建 Authentication对象

AuthenticationProvider:用于验证登录逻辑,对Authentication进行进一步的身份认证

AuthenticationProvider

ProviderManager

您可以将多个AuthenticationProvider实例注入到ProviderManager。每个AuthenticationProvider执行特定类型的身份验证。

例如,DaoAuthenticationProvider支持基于用户名/密码的身份验证,同时JwtAuthenticationProvider支持对 JWT 令牌进行身份验证。

DaoAuthenticationProvider

输入Username和Password,返回UserDetails和Authorities

作用:是一个AuthenticationProvider,用于校验账号密码

SecurityContextHolder

Spring Security 身份验证模型的核心是SecurityContextHolder,它存在于TreadLocal中,

设置SecurityContextHolder

不能直接通过SecurityContextHolder.getContext().setAuthentication(authentication)来设置Holder中的context,否则多线程情况下会出现问题。应该为每个线程创建单独的实例:

SecurityContext context = SecurityContextHolder.createEmptyContext(); 
Authentication authentication =
    new TestingAuthenticationToken("username", "password", "ROLE_USER"); 
context.setAuthentication(authentication);

SecurityContextHolder.setContext(context); 

访问当前经过身份验证的用户

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
  • 默认情况下,SecurityContextHolder使用 ThreadLocal来存储这些详细信息。
  • ThreadLocal如果在处理当前主体的请求后注意清除线程,Spring Security 的FilterChainProxy确保SecurityContext始终清除。
  • 三者包含关系:SecurityContextHolder→ SecurityContext → Authentication

Authentication中包含:

  • principal:标识用户。当使用用户名/密码进行身份验证时,这通常是UserDetails.

  • credentials: 通常是密码。很多情况下,这个是在用户通过认证后清除的,以保证不被泄露。

UserDetailsUserDetailsService关系:

UserDetails由UserDetailsService返回。DaoAuthenticationProvider验证UserDetails,然后返回一个Authentication,该Authentication的主体是配置的UserDetailsService返回的UserDetails。