Spring-Security-文档笔记之认证组件

1. 认证组件列表

  • SecurityContextHolder
    存储认证过的用户的详细信息
  • SecurityContext
    包含在SecurityContextHolder中, 存储当前已认证用户的信息(Authentication对象)
  • Authentication
    提供给AuthenticationManager以提供用户凭证(密码), 或者当前用户
  • GrantedAuthority
    授予用户的权限.
  • AuthenticationManager
    决定调用哪个身份认证过滤器
  • ProviderManager
    AuthenticationManager最常用的实现.
  • AuthenticationEntryPoint
    用来向客户端请求凭证(如重定向到登录页面, 或返回一个www-authenticate响应)
  • AbstractAuthenticationProcessingFilter
    用于进行认证的基本Filter.

2. SecutiryContextHolder

SecutiryContextHolder用于存储已认证用户的信息, 它不关心用户是如何通过认证的, 只要包含一个值, 则这个值将被用来作为一个已认证用户. 这是一个jvm设置, 因此其所有方法都是静态的.

通过配置指定相关策略. 其实现被委托给 SecurityContextHolderStrategy. 策略指定有两种方法, 一种是系统属性, 一种是调用静态方法.

其策略有三种:

  • ThreadLocal:
    默认, 使用一个ThreadLocal来存储用户信息, 因此在同一个线程中可以获取到用户信息.
  • InheritableThreadLocal:
    使用一个InheritableThreadLocal存储用户信息, 可以当前线程创建的子线程中也可以获取到用户信息.
  • Global:
    全局共享一个SecurityContext.

获取用户信息:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection authorities = authentication.getAuthorities();

类图:


image.png

3. SecurityContext

存储Authentication对象.

4. Authentication

在成功调用AuthenticationManager.authenticate(Authentication)方法后, 用于存储已认证用户的信息.
如果其authenticated属性值为false, Spring Security都将会对其进行验证.

Collection getAuthorities()用于获取授予认证主体的权限, 当没有权限时应返回空集合,而不是null.

Object getDetails()方法用于存储认证请求信息, 如IP地址, 凭证序列号等.

Object getPrincipal() : 在使用用户名和密码登录验证的请求中, 在认证成功之前, 这通常是用户名, 认证成功后, 这通常是一个UserDetails对象.

boolean isAuthenticated(): 用于指示AbstractSecurityInterceptor是否将当前的Authentication对象传递给AuthenticationManager进行身份验证.

5. GrantedAuthority

用于表示用户所获取的权限, 如角色. 如果使用用户名密码认证, 权限应由UserDetailsService加载.
它用字符串来表示, 以便能进行精确匹配.

6. AuthenticationManager

用于处理认证请求. 认证后会将用户信息存储到SecurityContext中. 其最常用的实现为ProviderManager.

必须对以下异常进行验证:

  • 如果用户被禁用,则应抛出DisabledException.
  • 如果用户被锁定, 则应抛出LockedException.
  • 如果凭证错误, 则必须抛出badcredentialexception。

Authentication authenticate(Authentication authentication) throws AuthenticationException: 如果调用成功则返回一个完全填充(包含了较全面的用户信息)的Authentication对象.

7. ProviderManager

最常用的AuthenticationManager实现. 它包含一个AuthenticationProvider集合. 每个provider对应一种身份验证方式, 因此通过AuthenticationManager可以支持多种身份验证方式. 如果请求没有相应的provider, 则将抛出ProviderNotFoundException.

image.png

ProviderManager遍历每个provider, 如果有一个provider返回非null结果, 则将不再调用后续未调用的provider.

此外, ProviderManager还可以配置一个parent, 当ProviderManager无法进行认证时, 可以调用这个parent. 这样可以在有多个ProviderManager实例时, 通过parent来处理公共认证方式. parent可以是任何AuthenticationManager实例, 但通常为ProviderManager.

ProviderManager还负责在认证成功后清除用户凭证(密码). 其eraseCredentialsAfterAuthentication属性值默认为true. 这对于通过缓存用户信息再进行认证的场景可能有影响(因为密码被清除了). 解决方式是设置eraseCredentialsAfterAuthentication为false.

认证事件
可通过AuthenticationEventPublisher来发布认证事件(成功,失败). 默认是一个Null实现(不发布事件). 因此如果需要发布事件,则需要注入对应的bean(DefaultAuthenticationEventPublisher). ProviderManager的parent通常不需要配置publisher, 因为manager可以对parent的认证结果发布相应的事件, 从而造成事件 的重复发布.

AuthenticationManager类图:


image.png

7. AuthenticationProvider

定义认证方式.

8. AuthenticationEntryPoint

ExceptionTranslationFilter中用来定义认证方案. 即返回给客户端响应以要求客户端提供何种方式的认证.

类图:


image.png

9. AbstractAuthenticationProcessingFilter

身份验证的一个基础Filter.


image.png
  1. 用户提交认证请求后, 它将从请求中获取相关参数并创建一个Authentication对象(对象类型取决于其实现类).
  2. Authentication对象被传递给AuthenticationManager进行验证处理.
  3. 如果验证不通过, 将清除SecurityContextHolder; 调用RememberMeService.loginFail(如果配置了remeberme); 调用AuthenticationFailureHandler. 如果验证通过, 通知SessionAuthenticationStrategy有一个新的登录; 存储AuthenticationSecurityContextHolder, SecurityContextPersistenceFilter保存这个SecurityContextHttpSession; 如果配置了remeberme, 调用RemeberMeService.loginSuccess; ApplicationEventPublisher发布一个InteractiveAuthenticationSuccessEvent, 调用AuthenticationSuccessHandler.

类图:


image.png

你可能感兴趣的:(Spring-Security-文档笔记之认证组件)