SpringSecurity的执行流程超详细讲解
SpringSec的执行流程
- 首先就是SpringSecurity的认证流程:
-
在SpringSecurity中有很多过滤器,其中有一个过滤器UserNamePassWordAuthenticationFilter
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0msXNUtZ-1663492817896)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918163837530.png)]](https://images2.imgbox.com/6a/f9/JyGzMdL0_o.png)
-
认证流程都是在这个过滤器进行处理的(这个过滤器是对/login的post请求做拦截,校验表单中用户名,密码)
-
然后在查看它的父类
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgLv1uax-1663492817897)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918164715019.png)]](https://images2.imgbox.com/c6/9c/dAPc8j6e_o.png)
-
然后找到他的doFilter方法

-
这里面就进行了一个判断,判断是否是Post提交,是不是解答了上面的疑问?为什么只对post请求做拦截,原因就在这。
-
如果不是Post请求,则进行放行。
-
接着来看源码
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ut4uxOoA-1663492817897)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918165830020.png)]](https://images2.imgbox.com/75/2b/7nDZxn0l_o.png)
-
第一步断点:这个不就是用来封装用户信息的那个类,(详情见文章末尾)
-
第二步断点:下面调用这个方法的意思是:调用子类UserNamePasswordAuthentacationFilter中的attemptAuthentication方法,得到表单数据,进行身份认证,如果认证成功,返回一个authReuslt,把这个对象封装到Authentication中去。
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eVy0A3cl-1663492817898)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918170019560.png)]](https://images2.imgbox.com/c4/bf/0VtwiREL_o.png)
-
接着往下看源码:
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CXyVavew-1663492817898)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918170438644.png)]](https://images2.imgbox.com/94/bd/Hf8uZX8b_o.png)
-
这行是不是看到熟悉的单词(Session),这行代码的含义是:配置Session的策略处理。比如:我有很多用户,我要配置session的最大并发数,如果没有配置,则不执行。
-
接着来看:
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxMtExz2-1663492817898)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918170909817.png)]](https://images2.imgbox.com/e9/6c/0G2l7oXW_o.png)
-
注意看这里是一个try,catch,有成功就肯定有失败,这步就是如果认证失败,则抛出异常,执行认证失败的方法。也就是unsuccessfulAuthentication(request,response,var8)。所以说这个失败处理并不是直接处理,而是通过抛出异常,由异常处理器处理(ExceptionTranslationFIlter:用来处理在认证授权过程中抛出的异常)
-
接着来看
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PZn9duM6-1663492817898)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918171251125.png)]](https://images2.imgbox.com/ee/2e/981qad7r_o.png)
-
如果认证成功,就来到了这里, 这个continueChainBeforeSuccessxxxx默认为false,如果认证成功,则变为true,执行后续操作。
-
-
- 总结:
首先发送一个请求,会被UserNamePasswordAuthenticationFIlter拦截到, 在这里先判断是不是Post提交,判断之后调用父类方法。如果不是的话做放行,如果是的话做认证,并调用子类的attemptAuthentication方法去查数据库返回UserDetails,把认证成功的数据封装到这个Authentication对象中去,并且做一个session策略的设置,当认证失败,做异常抛出,掉认证失败方法。认证成功,把this.continueChainxxx变为true,调认证成功的方法。
-
这个是总体的认证流程图
![- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-msQhGnBT-1663492817899)(C:/Users/swy/AppData/Roaming/Typora/typora-user-images/image-20220918164025033.png)]](https://images2.imgbox.com/53/99/dJ20IMxs_o.png)
- 当进行登录的请求时,首先会进入UesrNamePassWordAuthentacationFilter过滤器里面, 第一次登录的话就是未认证,然后通过AuthenticationManager这个类委托AuthenticationProvider去关联UserDetailService去查询数据库,判断用户是否是数据库中的用户,这就是认证的过程。
- 当认证成功之后,把查询到的数据封装到UserDetails中去,然后被Authentication进行封装(认证之后的信息)