首页 > 编程语言 >SpringSecurity表单登录流程源码分析

SpringSecurity表单登录流程源码分析

时间:2022-12-01 18:08:42浏览次数:40  
标签:SpringSecurity 这里 检查 调用 UsernamePasswordAuthenticationToken 认证 源码 user 表单


先看看这种核心流程图

SpringSecurity表单登录流程源码分析_表单


这张图是SpringSecurity认证涉及到的核心类

SpringSecurity表单登录流程源码分析_ide_02


让应用Debug启动

点击表单登录

进入到

SpringSecurity表单登录流程源码分析_ide_03


这个就是上图中的绿色过滤器 , 这个类中首先进入attemptAuthentication这个方法,获取用户名密码,然后用获取到的用户名密码构建了一个UsernamePasswordAuthenticationToken这个对象

SpringSecurity表单登录流程源码分析_构造函数_04


SpringSecurity表单登录流程源码分析_表单_05


顶层就是实现了Authentication,这个Authentication实际上就是封装登录这的认证信息,接着上面构建UsernamePasswordAuthenticationToken对象就会调用下面的构造方法

SpringSecurity表单登录流程源码分析_表单_06


这里会向父类传递一个null,

SpringSecurity表单登录流程源码分析_ide_07


因为代码执行到这一步是还没有进行认证,所以这里还不知道用户权限,所以这里会向父类传递权限为null,回到UsernamePasswordAuthenticationToken类的public UsernamePasswordAuthenticationToken(Object principal, Object credentials) 构造方法

UsernamePasswordAuthenticationToken两个参的构造函数并设置认证状态为false

SpringSecurity表单登录流程源码分析_ide_08

setAuthenticated(false);

这段代码时标识是否身份认证,上面讲到程序运行到这里是没有进行身份认证的,所以这里传入false,然后回到UsernamePasswordAuthenticationFilter类的attemptAuthentication方法

SpringSecurity表单登录流程源码分析_ide_09


这个setDetails方法会向请求的一些信息放到UsernamePasswordAuthenticationToken,包括请求中机器的ip,session这些东西

在往下走

SpringSecurity表单登录流程源码分析_表单_10


这一行代码就会进入到第二张流程图中的AuthenticationManager,AuthenticationManager自己并不包含验证的逻辑,他的作用是用来管理第二张图的AuthenticationProvider,向下走会进入这个类的

SpringSecurity表单登录流程源码分析_构造函数_11


这个方法

SpringSecurity表单登录流程源码分析_ide_12


这里循环中会拿到整个系统中所有实现AuthenticationProvider的实现类,这里上面提到的AuthenticationManager就是来收集并管理所有AuthenticationProvider的实现类,这里就会循环挨个去比对上面AuthenticationToken类型,也就是对比

SpringSecurity表单登录流程源码分析_ide_13

return this.getAuthenticationManager().authenticate(authRequest);

这里找到DaoAuthenticationProvider

传入的这个UsernamePasswordAuthenticationToken,这里不同的Provider支持的Authentication类型是不一样的,根据传入的Authentication类型这里会挑出一个进行校验处理,回到上面的循环中

SpringSecurity表单登录流程源码分析_表单_14


这里表单登录的活就会找到DaoAuthenticationProvider,

SpringSecurity表单登录流程源码分析_构造函数_15


这里表单登录的实际校验逻辑是写在AbstractUserDetailsAuthenticationProvider类中的

SpringSecurity表单登录流程源码分析_ide_16

user = retrieveUser(username,
(UsernamePasswordAuthenticationToken) authentication);

这里调用了一个retrieveUser方法获取到一个user对象,这里的user就是UserDetails接口

retrieveUser这个方法是个抽象方法

SpringSecurity表单登录流程源码分析_表单_17


这里在DaoAuthenticationProvider类中有这个方法的实现

SpringSecurity表单登录流程源码分析_构造函数_18

loadedUser = this.getUserDetailsService().loadUserByUsername(username);

这行代码就再调用我们自己写的UserDetails接口的实现,这里就和​​SpringSecurity表单认证​​ 这篇文章中自定义实现中的UserDetailsService类关联上了,UserDetailsService类就是在上面这句代码中调用的,调用的结果就是我们在UserDetailsService类中loadUserByUsername方法返回的结果,这里结果拿到后回到AbstractUserDetailsAuthenticationProvider类中的

SpringSecurity表单登录流程源码分析_表单_19


如果没拿到会有一个异常抛出,拿到后会有一个

preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user,
(UsernamePasswordAuthenticationToken) authentication);

这里会做一个预检查,这里预检查也就是​​SpringSecurity表单认证​​这篇文章中提到的MyUserDetailsService中的第二个构造函数多4个构造参数的那个传入的用户状态

SpringSecurity表单登录流程源码分析_构造函数_20


SpringSecurity表单登录流程源码分析_表单_21


这里根据调用则来区分具体实现,那么这里调用者为preAuthenticationChecks

所以选

SpringSecurity表单登录流程源码分析_表单_22


这里上面MyUserDetailsService中的第二个构造函数多4个构造参数传入的是4个,最后一个是在下面单独验证,往下继续

做完这个预检查后又会调用additionalAuthenticationChecks

SpringSecurity表单登录流程源码分析_表单_23


这是个附加检查

SpringSecurity表单登录流程源码分析_表单_24


这里又是一个抽象方法,这里又会回到DaoAuthenticationProvider中的实现,这个实现就是上面找到的DaoAuthenticationProvider,上面有做标记,全文搜索一下

SpringSecurity表单登录流程源码分析_构造函数_25


密码校验

SpringSecurity表单登录流程源码分析_ide_26


这里走完回到附加检查代码哪里,这里通过后往下走

SpringSecurity表单登录流程源码分析_表单_27


会进入一个后检查,这里后检查就是相对预检查哪里的,因为预检查只检查了三个状态,那么这里既是检查第四个值代表的用户状态,那么这里具体的实现也看调用者,

SpringSecurity表单登录流程源码分析_表单_28


那么走到这里所有的检查都通过了,那么就可以认为这个用户认证时成功的

SpringSecurity表单登录流程源码分析_构造函数_29


那么这里认证成功后就会将获取到的用户信息user、authentication认证请求信息用createSuccessAuthentication来创建

SpringSecurity表单登录流程源码分析_构造函数_30


这里createSuccessAuthentication就是从新来new UsernamePasswordAuthenticationToken,只是这里就不是调用两个参数的构造函数了,而是三个构造参数的函数这里可以全文搜索两个参的构造

UsernamePasswordAuthenticationToken两个参的构造函数并设置认证状态为false

实际上这里多的一个参数就是authorities

SpringSecurity表单登录流程源码分析_表单_31


这里会调用父类super设置权限,并将认证状态改为true,标识认证成功,那么运行到这里就认证流程就已经走完了,那么此时一路return返回,就会回到

SpringSecurity表单登录流程源码分析_构造函数_32


那么在往下走

SpringSecurity表单登录流程源码分析_ide_33


SpringSecurity表单登录流程源码分析_ide_34


实际上这里就是在调用我们自己写的登录成功后的处理器也就是第一部分上面写的自定义登录成功、失败处理逻辑,那么认证成功的逻辑就是这样的,那么在整个流程中任何一个步骤不过就会catch异常捕获

SpringSecurity表单登录流程源码分析_构造函数_35


那么这里捕获的异常都会到我们自己的认证失败处理器上

SpringSecurity表单登录流程源码分析_构造函数_36


我们的认证失败处理器会实现这个接口,重写这个方法。

那么到这里,我们上面的第二张流程图中的所有步骤就走完了,包括认证成功、失败、密码加密,那么都被串起来了,整个认证的源码分析流程就基本上完了!

FilterSecurityInterceptor


标签:SpringSecurity,这里,检查,调用,UsernamePasswordAuthenticationToken,认证,源码,user,表单
From: https://blog.51cto.com/u_15899048/5903523

相关文章