SpringSecurity认证流程

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

案例代码


ChaiRongD/Demooo - Gitee.com


源码分析


初始化


1.png


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


2.png


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


3.png


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


4.png


登陆验证过程


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


5.png


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


6.png


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


7.png


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


否则创建一个新的SecurityContext。


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


8.png


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


9.png


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


10.png


获取用户信息


@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;  


目录
相关文章
|
8月前
|
安全 Java 数据安全/隐私保护
SpringSecurity 认证流程
通过了解SpringSecurity核心组件后,就可以进一步了解其认证的实现流程了。
62 0
|
9月前
|
安全 Java 数据库
SpringSecurity-4-认证流程源码解析
SpringSecurity-4-认证流程源码解析
49 0
|
9月前
|
存储 安全 前端开发
详解SpringSecurity认证(下)
详解SpringSecurity认证(下)
87 0
|
5月前
|
安全 Java API
盘点认证框架 : SpringSecurity 基础篇
SpringSecurity 应该是最常见的认证框架了 , 处于Spring体系中使他能快速地上手 , 这一篇开始作为入门级开篇作 , 来浅浅地讲一下SpringSecurity 的整体结构.
|
7月前
|
安全 API
04 Shrio身份认证流程
04 Shrio身份认证流程
26 0
04 Shrio身份认证流程
|
7月前
11 Shrio 授权流程
11 Shrio 授权流程
18 0
|
9月前
|
安全 前端开发 Java
详解SpringSecurity认证(上)
详解SpringSecurity认证(上)
102 0
|
10月前
|
安全 API 数据库
SpringSecurity基础-授权流程
授权一定是在认证通过之后,授权流程是通过FilterSecurityInterceptor拦截器来完成,FilterSecurityInterceptor通过调用SecurityMetadataSource来获取当前访问的资源所需要的权限,然后通过调用AccessDecisionManager投票决定当前用户是否有权限访问当前资源。授权流程如下
94 0
|
10月前
|
安全 API 数据库
五.SpringSecurity基础-授权流程
SpringSecurity基础-授权流程
|
10月前
|
JSON 前端开发 数据格式
SpringSecurity基础-认证授权结果处理
在传统的应用中,认证成功后页面需要跳转到认证成功页面或者跳转到个人中心页,但是在前后端分离的项目通常是使用Ajax请求完成认证,这时候我们需要返回一个JSON结果告知前端认证结果,然后前端自行跳转页面。 要做到上述功能,我们需要自定义认证成功处理器实现AuthenticationSuccessHandler接口复写 onAuthenticationSuccess方法,该方法其中一个参数是Authentication ,他里面封装了认证信息,用户信息UserDetails等,我们需要在这个方法中使用Response写出json数据即可
88 0