spring security 学习总结

1. springboot整合好security后, 当未进行登陆直接访问接口, 默认会跳转到security默认的登陆界面, 用户名为"admin" 密码打印在控制台, 并且也可以自己配置用户名和密码

2. 自定义登陆界面

首先编写一个登陆界面login.html, (将其放在resource/static目录下), 再定义一个配置类实现 WebSecurityConfigurerAdapter 接口, 配置如下属性

3.  当未进行登陆, 就去访问接口, security自动将跳转到登陆界面 (非前后端分离方式) , 登陆了之后才能正常访问接口

   注意 : .and().csrf().disable()必须配置, 不然不能实现页面跳转

配置登陆用户的信息 (先放置到内存中)

CSRF简介 :

4. 配置退出登陆

 

5. security如何记录你是否登陆? (源码分析)

1. 首先找到UsernamePasswordAuthenticationFilter过滤器, 查看其attemptAuthentication方法

1. 36--38行判断登陆方法是不是post请求

2. 39--43 行获取用户名和密码, 并判断是否为空

3. 44行实例化 UsernamePasswordAuthenticationToken (赋值用户名和密码,  是否拥有权限设置为false)

4. 45行 setDetails(request, authRequest)是将当前的请求信息设置到UsernamePasswordAuthenticationToken中

5. 进入最关键的46行, 调用authenticate方法,(AuthenticationManager 接口中的方法), 通过ctrl + h 观察其子实现类, 定位到ProviderManager类,查看authenticate方法

70行获取security支持的认证方式, 72行进行遍历, 当找到对应的认证方式之后执行83行, provider是AuthenticationProvider接口的子实现, 通过ctrl + h判断出抽象AbstractUserDetailsAuthenticationProvider

查看其authenticate方法

59行获取用户名, 61行从缓存中获取用户, 如果为空到66行, 查看retrieveUser方法

53行获取用户信息

80行对用户信息进行校验, 校验的主要是如下信息,  81行是对密码进行校验

38行根据自己指定的密码编码方式进行对比,  判断密码时候一致

接下来执行103行

111行创建UsernamePasswordAuthenticationToken对象, 调用三个参数的构造方法, 获取到权限

以上执行完毕,  会将用户的登陆信息记录到security的上下文中(SecurityContextPersistenceFilter过滤器)

6. security授权认证源码解析

1. 首先现在是已经登陆的状态,  向接口发送请求时, 首先会进度第一个过滤器SecurityContextPersistenceFilter,  查看他的dofilter方法

51行, 将request和response封装到HttpRequestResponseHolder中, 52行是关键,去SecurityContextRepository中去加载context上下文, 方法如下

接下来进入45行代码的方法中

84行获取SecurityContext对象, 因为已经登陆,  该值不为null, 之后返回

第53--55行没有搞懂是要做什么...,  之后返回securityContext

57 行将context存储到SecurityContextHolder中, 之后执行回调函数invoke

该方法中最关键的是62行, 进入该方法

125行是用来获取访问改接口需要的权限的集合, 141行获取登陆用户的信息以及拥有的权限, 接下来关键是146行, 进入该方法

175行就是验证权限最关键的代码

主要有三种认证规则, AffirmativeBased , ConsensusBased , UnanimousBased

AffirmativeBased : 不是全部否定即可通过

ConsensusBased : 满足比否定多即可通过

UnanimousBased : 有一条否定就不能通过

到此,  security的登陆认证功能分析完毕,  最后清除一些信息

69行, SecurityContextHolder清除SecurityContext,  70行将SecurityContext存到SecurityContextRepository中

到此有一个问题 SecurityContextHolder为什么要清除SecurityContext?

           SecurityContext被SecurityContextHolder存储在ThreadLocal中, 而这个thread刚好是存在于servlet容器的线程池中的,如果不清除,当后续请求又从线程池中分到这个线程时,程序就会拿到错误的认证信息

http://www.cocoachina.com/articles/42621  全面解释

7. 访问数据库获取用户, 以及用户拥有的权限去请求接口

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值