一、认证流程图
假设系统当前没有任何用户登录且没有任何的用户缓存。认证流程如下图所示:
二、过程详解
1) 用户发起表单验证后,首先会被UsernamePasswordAuthenticationFilter
捕获。
UsernamePasswordAuthenticationFilter
中根据用户表单信息中的用户名和密码构建UsernamePasswordAuthenticationToken
,并将其交给AuthenticationManager
实现认证过程。
但在大部分情况下,我们会在自定义的表单处理接口中构建UsernamePasswordAuthenticationToken
,然后通过authenticationManagerBuilder.getObject()
获得AuthenticationManager
,进而实现认证流程。
UsernamePasswordAuthenticationToken
及其类图继承关系如下所示:
此外,AuthenticationManager
本身不包含任何的认证逻辑,其核心是管理所有的AuthenticationProvider
,本质上是由AuthenticationProvider
来实现认证。
2) 然后到ProviderManager
,该类是AuthenticationManager
的实现类,负责管理AuthenticationProvider
,每一种AuthenticationProvider
表示一种认证逻辑(Spring Security 支持多种认证逻辑)。
通过ProviderManager
的authenticate()
方法进一步实现认证过程,如下图所示:
通过getProviders().iterator()
得到含AuthenticationProvider
的迭代器,并通过provider.supports()
方法判断当前的AuthenticationProvider
是否支持当前的认证逻辑。若支持,接下来交由AbstractUserDetailsAuthenticationProvider
的authenticate()
实现进一步的认证。
3) 接下来的信息认证是交给AuthenticationProvider
的抽象类AbstractUserDetailsAuthenticationProvider
来实现,实现方法主要是authenticate()
。
由 DaoAuthenticationProvider
实现retrieveUser()
方法,如下所示:
4) 成功获得UserDetails
后,开始进行一系列的认证:
用户身份信息的认证校验会经过前置校验、额外校验和后置校验。若所有的认证校验均通过会调用createSuccessAuthentication()
方法并返回认证信息,否则会抛出响应的异常来说明认证不通过。
createSuccessAuthentication()
方法的调用过程如下所示:
在该方法中重新创建了UsernamePasswordAuthenticationToken
,且此时用户身份已认证通过,所以将authorities
注入,并设置authenticated
为true
,即已认证。
5) 最后认证信息会传回UsernamePasswordAuthenticationFilter
,并在其父类AbstractAuthenticationProcessingFilter
的doFilter()
中,根据认证的成功或失败调用相应的handler
。