前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringSecurity认证流程

SpringSecurity认证流程

作者头像
CBeann
发布2023-12-25 19:07:18
1430
发布2023-12-25 19:07:18
举报
文章被收录于专栏:CBeann的博客CBeann的博客

写作目的

最近在学习SpringSecurity,中间就遇到了一个问题:我在浏览器中第一次输入localhost:8080/hello,提示我没有登陆,自动跳转到登陆页面,等我登陆成功后,我在输入localhost:8080/hello,就成功访问了,验证第二次的时候,验证信息是存储在哪呢? 跟完源码发现:存储信息存在session中,然后每次请求都在session中取出并且放在ThreadLocal中。

案例代码

ChaiRongD/Demooo - Gitee.com

源码分析

初始化

我们从WebSecurityConfiguration类的加载开始,因为这个类带有@Configuration,从这里出发也说的过去。这个类有一个带有@Autowired的方法,所以在Bean的生命周期的里会执行这个方法,执行这个方法的时候会执行this.webSecurity=xxx ,创建webSecurity。

然后创建SpringSecurityFilterChain对象,并且name 等于常量 "springSecurityFilterChain"

其中springSecurityFilterChain的类型是FilterChainProxy,里面有一个类型是DefaultSecurityChain属性filterChains,filterChains里包含11个默认的Filter。

登陆验证过程

在浏览器中输入http://localhost:8080/login (这个地址是/login是配置的),跳转到登陆页面;输入正确的用户名(zhangsan)和密码(123456)后,我们看这个请求的执行流程。

我们从DelegatingFilterProxy.doFilter()开始,首先获取applicationContext,然后从applicationContext中获取DefalutSecurityFilterChain(包含11个Filter)

把11个Security Filter 和FilterChain 封装成VirtualFilterChain,执行VirtualFilterChain.doFilter()方法

获取SecurityContext对象。session存在并且session.getAttribute("SPRING_SECURITY_CONTEXT")!=null,返回SecurityContxt;

否则创建一个新的SecurityContext。

并且把SecurityContext放在SecurityContextHolder(ThreadLocal)中。

AbstractAuthenticationProcessingFilter.doFilter()方法里面做了认证,并且有认证成功后的 自定义处理逻辑

认证成功后。把认证成功的信息保存在session中

获取用户信息

代码语言:javascript
复制
@RequestMapping("/hello")
    @ResponseBody
    public String hello(Authentication authentication) {
        System.out.println(authentication.getName());
        return "hello security";
    }

    @RequestMapping("/hello2")
    @ResponseBody
    public String hello2(Authentication authentication) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        return "hello security2";
    }

我们可以在controller层获取,也可以在SecurityContextHolder(ThreadLocal)中获取。

为什么可以在 SecurityContextHolder中获取,因为每次请求都会在session中获取认证信息,并且保存在ThreadLocal中。

拓展

request.getSession(true/false)的区别

HttpServletRequest.getSession(ture)等同于 HttpServletRequest.getSession() HttpServletRequest.getSession(ture)表示如果有session返回,没有创建一个返回 HttpServletRequest.getSession(false)表示如果有session返回,没有就为null;

ThreadLocal笔记

ThreadLocal笔记_CBeann的博客-CSDN博客

参考

基于注解的Spring Security原理解析_icarusliu的专栏-CSDN博客_security注解

request.getSession()和request.getSession(true/false)的理解_朱智文的专栏-CSDN博客_request.getsession()

ThreadLocal笔记_CBeann的博客-CSDN博客

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写作目的
  • 案例代码
  • 源码分析
    • 初始化
      • 登陆验证过程
        • 获取用户信息
        • 拓展
          • request.getSession(true/false)的区别
            • ThreadLocal笔记
            • 参考
            相关产品与服务
            对象存储
            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档