概要
技术细节
1:UsernamePasswordAuthenticationFilter:
首先将用户名和密码封装进UsernamePasswordAuthenticationToken(UsernamePasswordAuthenticationToken的继承体系)
图1:
图2:
接着调用this.getAuthenticationManager().authenticate(authRequest);
(getAuthenticationManager()方法返回AuthenticationManager)
图3:
进入AuthenticationManager
2:ProviderManager
图4:
图5:
标记1:
AuthenticationProvider provider = (AuthenticationProvider)var9.next();
3:进入AuthenticationProvider
AbstractUserDetailsAuthenticationProvider类实现了AuthenticationProvider接口
4:AbstractUserDetailsAuthenticationProvider
DaoAuthenticationProvider继承了AbstractUserDetailsAuthenticationProvider类
在AbstractUserDetailsAuthenticationProvider中authenticate方法中调用this.retrieveUser()方法。
如果父类中没有retrieveUser方法,就在其子类中找。
5:DaoAuthenticationProvider
DaoAuthenticationProvider中this.getUserDetailsService()返回UserDetailsService接口
6:UserDetailsService
UserDetailsService接口下面有个loadUserByUsername方法
7:自己写的功能
重写了loadUserByUsername方法,之后DaoAuthenticationProvider就会调用自己写的方法,实现自己的业务
查询数据库表,认证用户是否存在,返回UserDetails对象
8:返回数据至AbstractUserDetailsAuthenticationProvider
将数据层层返回至AbstractUserDetailsAuthenticationProvider
接着往下对密码进行校验
抽象,进入实现
将用户输入的密码,与userDetails(封装了从数据库查询的用户名和密码)中密码进行比对,错了就报错
注:
passwordEncoder可以在配置类中配置
9:返回数据至UsernamePasswordAuthenticationFilter
attemptAuthentication方法是父类AbstractAuthenticationProcessingFilter中的抽象方法
在其父类中dofilter调用了attemptAuthentication方法并返回了
Authentication authenticationResult
successfulAuthentication:身份验证时
successfulAuthentication:身份验证成功
unsuccessfulAuthentication:身份验证失败
进入successfulAuthentication方法
10:将Authentication存入上下文对象中
11:拓展:自定义
AuthenticationFailureHandler
验证成功和验证失败会调用下面这两个对象中的方法
而,这两个对象都继承了AuthenticationFailureHandler方法,所以可以自定义成功和失败后要执行的业务逻辑,只需要自定义的类重写AuthenticationFailureHandler接口中的方法
例子:
在配置类中引入
小结
自己翻了翻源码,浅显分析了一下源码流程,如有不妥之处的地方请指正