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,简单的一些概念上 ...
随机推荐
- Dubbo配置引发的一个问题--- Duplicate spring bean id
1.原因 因项目业务需要,要调用RPC框架,项目原本已经依赖了很多RPC接口需要启动时加载,所以准备做成启动时不预加载. 就是在配置的时候加上check=false. 官方文档解释的作用,就是Dubb ...
- 搭建centos7的开发环境2-单机版Hadoop2.7.3配置
最近公司准备升级spark环境,主要原因是生产环境的spark和hadoop版本都比较低,但是具体升级到何种版本还不确定,需要做进一步的测试分析.这个任务对于大数据开发环境配置有要求,这里记录一下配置 ...
- C#语言中的XmlSerializer类的XmlSerializer.Serialize(Stream,Object)方法举例详解
在对象和 XML 文档之间进行序列化和反序列化操作. XmlSerializer 使您能够控制如何将对象编码为 XML. 命名空间: System.Xml.Serialization程序集: S ...
- Lenghth of Last Word
description: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', ...
- [ SSH框架 ] Struts2框架学习之二
一.Struts2访问Servlet的API 前面已经对 Struts2的流程已经执行完成了,但是如果表单中有参数如何进行接收又或者我们需要向页面保存一些数据,又要如何完成呢?我们可以通过学习 Str ...
- require.js配置路径的用法和css的引入
前端开发在近一两年发展的非常快,JavaScript作为主流的开发语言得到了前所未有的热捧.大量的前端框架出现了,这些框架都在尝试着解决一 些前端开发中的共性问题,但是实现又不尽相同.通常一般的前端加 ...
- 【Quartz】常用方法的使用方式(三)
前言 总结了一下quartz组件的一些常用方法,以备将来不时之需.哈哈,看着挺简单有些好是值得笔记一下的.好记性不如烂笔头吗? 代码部分: 方法类内容: public class Example ...
- element-ui bug及解决方案
1.element-ui 使用MessageBox后弹窗显示异常 解决方案:去掉Vue.use(MessageBox); 2.element-ui 分页切换后若改变总数会导致请求两次 解决方案:< ...
- 以Kafka Connect作为实时数据集成平台的基础架构有什么优势?
Kafka Connect是一种用于在Kafka和其他系统之间可扩展的.可靠的流式传输数据的工具,可以更快捷和简单地将大量数据集合移入和移出Kafka的连接器.Kafka Connect为DataPi ...
- 在webpack里使用jquery.mCustomScrollbar插件
malihu-custom-scrollbar-plugin是一个依赖jquery的自定义网页滚动条样式插件 网站:http://manos.malihu.gr/jquery-custom-conte ...