shiro的SecurityUtis
接着上一篇来继续分析shiro源码
这篇主要讲解shiro里面的SecurityUtils
首先我们看该类供我们在业务中用的仅有两个get方法,那么这两个get方法获取的subject和sercurityManager怎么来的,我们具体分析

首先我们已经知道每次请求在被拦截后都会走AbstractShiroFilter里的doFilterInternal方法,如果不清楚请先看我的《spring集成shiro登陆流程》的上下篇。
AbstractShiroFilter
其中有这么段代码
//调用DelegatingSubject的execute(Callable<V> callable)方法
subject.execute(new Callable() {
public Object call() throws Exception {
updateSessionLastAccessTime(request, response);
executeChain(request, response, chain);
return null;
}
});
这里调用了DelegatingSubject的execute(Callable<V> callable)方法
DelegatingSubject
进来看
public <V> V execute(Callable<V> callable) throws ExecutionException {
//这里创建了一个Callable对象,进去看
Callable<V> associated = associateWith(callable);
try {
return associated.call();
} catch (Throwable t) {
throw new ExecutionException(t);
}
}
//继续
public <V> Callable<V> associateWith(Callable<V> callable) {
//这里将subject对象传递到SubjectCallable
return new SubjectCallable<V>(this, callable);
}
SubjectCallable
注意看这里创建了一个SubjectThreadState对象
public SubjectCallable(Subject subject, Callable<V> delegate) {
this(new SubjectThreadState(subject), delegate);
}
//这个方法主要是将subject对象和securityManager 放在SubjectThreadState上下文
public SubjectThreadState(Subject subject) {
this.subject = subject;
SecurityManager securityManager = null;
//从subject中获取securityManager对象,每次请求都会将securityManager对象放到subject上下文, (DefaultSecurityManager#createSubject的ensureSecurityManager)
if ( subject instanceof DelegatingSubject) {
securityManager = ((DelegatingSubject)subject).getSecurityManager();
}
if ( securityManager == null) {
securityManager = ThreadContext.getSecurityManager();
}
this.securityManager = securityManager;
}
那么到这儿,在SubjectThreadState中就有了subject和securityManager对象
继续看到DelegatingSubject的execute方法
执行associated.call()
我们点进去看 SubjectCallable#call
SubjectCallable
//首先我们注意到doCall方法就是调用了Callable的call方法,也就是异步执行了executeChain(request, response, chain);方法,简单说就是调用验证等流水账然后进入我们的业务代码
//我们调用SecurityUtis.getSubject就是在doCall异步执行里用的
public V call() throws Exception {
try {
//我们发现执行目标业务之前有个bind方法
threadState.bind();
return doCall(this.callable);
} finally {
//执行完后会清空bind的数据
threadState.restore();
}
}
protected V doCall(Callable<V> target) throws Exception {
return target.call();
}
很有必要再进SubjectThreadState方法看看bind这个方法
SubjectThreadState
public void bind() {
SecurityManager securityManager = this.securityManager;this.originalResources = ThreadContext.getResources();
//清空ThreadContext里的数据
ThreadContext.remove();
//将subject和securityManager绑定到ThreadContext
ThreadContext.bind(this.subject);
if (securityManager != null) {
ThreadContext.bind(securityManager);
}
}
走到这儿我们发现把subject和securityManager绑定到ThreadContext
那么这个ThreadContext就很重要了,必须看看
ThreadContext
//定义了个跟线程绑定的ThreadLocal
private static final ThreadLocal<Map<Object, Object>> resources = new InheritableThreadLocalMap<Map<Object, Object>>();
//将subject和当前线程绑定
public static void bind(Subject subject) {
if (subject != null) {
put(SUBJECT_KEY, subject);
}
}
//将securityManager和当前线程绑定
public static void bind(SecurityManager securityManager) {
if (securityManager != null) {
put(SECURITY_MANAGER_KEY, securityManager);
}
}
那么我们应该再看看SecurityUtils的两个get方法
//从ThreadContext中获取,没有就创建一个并绑定
public static Subject getSubject() {
Subject subject = ThreadContext.getSubject();
if (subject == null) {
subject = (new Subject.Builder()).buildSubject();
ThreadContext.bind(subject);
}
return subject;
}
//先从ThreadContext中获取,如果没有则从SecurityUtils中获取,如果没有就直接从SubjceUtils中获取(如果是spring项目,那么在spirng的配置文件长会配置)
public static SecurityManager getSecurityManager() throws UnavailableSecurityManagerException {
SecurityManager securityManager = ThreadContext.getSecurityManager();
if (securityManager == null) {
securityManager = SecurityUtils.securityManager;
}return securityManager;
}
看到这儿我们了解到了为什么我们在程序中调用SecurityUtils的getSubject会有值了
小结:
当我们登陆后,每次请求都会将Subject对象和SecurityManager对象与当前线程绑定,在执行完业务逻辑后,会将这些数据与当前线程解绑
那么我们得到了SecurityManager对象后,那么它依赖的数据就轻而易举的可以愉快的拿到了
注:有不好或者错误的地方还请看官在评论区给指出,意见宝贵。
shiro的SecurityUtis的更多相关文章
- Shiro learning - 入门案例(2)
Shiro小案例 在上篇Shiro入门学习中说到了Shiro可以完成认证,授权等流程.在学习认证流程之前,我们应该先入门一个Shiro小案例. 创建一个java maven项目 <?xml ve ...
- shiro权限管理框架与springmvc整合
shiro是apache下的一个项目,和spring security类似,用于用户权限的管理‘ 但从易用性和学习成本上考虑,shiro更具优势,同时shiro支持和很多接口集成 用户及权限管理是众多 ...
- springmvc 多数据源 SSM java redis shiro ehcache 头像裁剪
获取下载地址 QQ 313596790 A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:31359679 ...
- java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单; 技术:313596790freemaker模版技术 ,0个代码不用写 ...
- springmvc SSM shiro redis 后台框架 多数据源 代码生成器
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单 下载地址 ; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类 ...
- springmvc SSM 多数据源 shiro redis 后台框架 整合
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单 下载地址 ; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类 ...
- SpringMVC+Shiro权限管理【转】
1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证层 6.Shiro-applica ...
- shiro的使用2 灵活使用shiro的密码服务模块
shiro最闪亮的四大特征是认证,授权,加密,会话管理. 上一篇已经演示了如何使用shiro的授权模块,有了shiro这个利器,可以以统一的编码方式对用户的登入,登出,认证进行管理,相当的优雅. 为了 ...
- shiro的使用1 简单的认证
最近在重构,有空学了一个简单的安全框架shiro,资料比较少,在百度和google上能搜到的中文我看过了,剩下的时间有空会研究下官网的文章和查看下源码, 简单的分享一些学习过程: 1,简单的一些概念上 ...
随机推荐
- redis资源未释放引发的问题
一.redis资源未释放的起因: N年前,在修改一个古老程序时,不小心把redis释放的这块给干掉了, if (jedis != null) { if (!isInProcess) { jedis.d ...
- java中Collections.sort()方法实现集合排序
1.Integer/String泛型的List进行排序 List <Integer> integerlist = new ArrayList<Integer>(); //定 ...
- go语言时间比较
local, _ := time.LoadLocation("Local") starttime, _ := time.ParseInLocation("2006-01- ...
- CentOS 6 安装HBase集群教程
hbase0.99.2安装包下载(链接:https://pan.baidu.com/s/1dR-HB3P6mzsXVW6sLI8uxQ 密码:4g1n) 首先需要安装 zookeeper(点击查看) ...
- 5月2日——iOS11定位失效问题
所存在的问题: (1)定位不能正常使用 (2)首次安装APP 时 "是否允许使用定位信息" 系统提示框不显示 iOS定位失效原因: 因为苹果现在增加了一项新的隐私保护功能 NSL ...
- python之Flask实现登录功能
网站少不了要和数据库打交道,归根到底都是一些增删改查操作,这里做一个简单的用户登录功能来学习一下Flask如何操作MySQL. 用到的一些知识点:Flask-SQLAlchemy.Flask-Logi ...
- 【机器学习】使用gensim 的 doc2vec 实现文本相似度检测
环境 Python3, gensim,jieba,numpy ,pandas 原理:文章转成向量,然后在计算两个向量的余弦值. Gensim gensim是一个python的自然语言处理库,能够将文档 ...
- 微信小程序开发资源汇总 💯
目录 官方文档 工具 插件 讨论 教程 视频教程 文章 代码 轮子 置顶 WePY:组件化的小程序开发框架
- 可能是史上最全的机器学习和Python(包括数学)速查表
新手学习机器学习很难,就是收集资料也很费劲.所幸Robbie Allen从不同来源收集了目前最全的有关机器学习.Python和相关数学知识的速查表大全.强烈建议收藏! 机器学习有很多方面. 当我开始刷 ...
- 十七、Hadoop学记笔记————Hbase入门
简而言之,Hbase就是一个建立在Hdfs文件系统上的数据库(mysql,orecle等),不同的是Hbase是针对列的数据库 Hbase和普通的关系型数据库区别如下: Hbase有一些基本的术语,主 ...