Shiro的subject实质上是当前执行用户的特定视图。

通过org.apache.shiro.SecurityUtils可以查询当前执行用户:

Subject currentUser = SecurityUtils.getSubject();

获取当前执行用户的session:

(在非web、非EJB的情况下,Shiro自动使用自带session;如果是web或者EJB应用,则Shiro自动使用HttpSession,不需要人为改变。)

Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );

案例一:

验证用户是否为认证用户:

if ( !currentUser.isAuthenticated() ) {//collect user principals and credentials in a gui specific manner//such as username/password html form, X509 certificate, OpenID, etc.//We'll use the username/password example here since it is the most common.//(do you know what movie this is from? ;) UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); //this is all you have to do to support 'remember me' (no config - built in!): token.setRememberMe(true); currentUser.login(token); }

验证失败,提示信息:

ry {currentUser.login( token );//if no exception, that's it, we're done!
} catch ( UnknownAccountException uae ) {//username wasn't in the system, show them an error message? } catch ( IncorrectCredentialsException ice ) { //password didn't match, try again? } catch ( LockedAccountException lae ) { //account for that username is locked - can't login. Show them a message? } ... more types exceptions to check if you want ... } catch ( AuthenticationException ae ) { //unexpected condition - error? }

案例二(展示当前用户信息):

//print their identifying principal (in this case, a username):
log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );

案例三(判断当前用户角色):

if ( currentUser.hasRole( "schwartz" ) ) {log.info("May the Schwartz be with you!" );
} else {log.info( "Hello, mere mortal." ); }

案例四(验证当前用户权限):

if ( currentUser.isPermitted( "lightsaber:weild" ) ) {log.info("You may use a lightsaber ring.  Use it wisely.");
} else {log.info("Sorry, lightsaber rings are for schwartz masters only."); }

案例五(退出登录):

currentUser.logout(); //removes all identifying information and invalidates their session too.

Shiro支持创建subject的实例,但不推荐。因为我们平常可以直接通过getSubject来获取当前执行用户。个别情况需要创建subject:

1.当前没有用户可以与系统进行交互,但是为保持系统的运行,需要假设一个用户,此时可以创建一个subject,比如admin用户。

2.集成测试时,需要创建一个临时的subject用以进入下一步的测试。

3.应用的后台进程运行的时候,需要一个subject。

(如果已经拥有了一个subject,但是需要和其他线程共享的话,需要调用Subject.associateWith*方法。)

subject的创建

案例六(Subject.Builder,创建subject,而无需知道其中细节,会访问到SecurityManager的SecurityUtils.getSecurityManager()方法。):

Subject subject = new Subject.Builder().buildSubject()

案例七(自建securityManager):

SecurityManager securityManager = //acquired from somewhere
Subject subject = new Subject.Builder(securityManager).buildSubject();

案例八(利用session创建新的subject):

Serializable sessionId = //acquired from somewhere
Subject subject = new Subject.Builder().sessionId(sessionId).buildSubject();

案例九(创建subject,并将其属性映射到验证属性中):

Object userIdentity = //a long ID or String username, or whatever the "myRealm" requires String realmName = "myRealm"; PrincipalCollection principals = new SimplePrincipalCollection(userIdentity, realmName); Subject subject = new Subject.Builder().principals(principals).buildSubject();

将自建的subject与线程进行绑定:

1.系统的自动绑定,Subject.execute*方法的调用。

2.手动的绑定。

3.利用已绑定的线程来绑定到新的线程,Subject.associateWith*方法的调用。

(subject与线程绑定,则可以在线程执行过程中取到信息;subject与线程取消绑定,则线程可以被回收。)

案例十(调用execute方法,参数为runable实例,实现subject的自动绑定与拆除):

Subject subject = //build or acquire subject
subject.execute( new Runnable() {public void run() {//subject is 'bound' to the current thread now //any SecurityUtils.getSubject() calls in any //code called from here will work } }); //At this point, the Subject is no longer associated //with the current thread and everything is as it was before

案例十一(调用execute方法,参数为callable实例,实现subject的自动绑定与拆除):

Subject subject = //build or acquire subject
MyResult result = subject.execute( new Callable<MyResult>() {public MyResult call() throws Exception {//subject is 'bound' to the current thread now //any SecurityUtils.getSubject() calls in any //code called from here will work ... //finish logic as this Subject ... return myResult; } }); //At this point, the Subject is no longer associated //with the current thread and everything is as it was before

案例十二(spring远程调用subject):

Subject.Builder builder = new Subject.Builder();
//populate the builder's attributes based on the incoming RemoteInvocation
...
Subject subject = builder.buildSubject();return subject.execute(new Callable() {public Object call() throws Exception { return invoke(invocation, targetObject); } });

线程池的清理:

Subject subject = new Subject.Builder()...
ThreadState threadState = new SubjectThreadState(subject);
threadState.bind();
try {//execute work as the built Subject
} finally { //ensure any state is cleaned so the thread won't be //corrupt in a reusable or pooled thread environment threadState.clear(); }

案例十三(callable):

Subject subject = new Subject.Builder()...
Callable work = //build/acquire a Callable instance.
//associate the work with the built subject so SecurityUtils.getSubject() calls works properly:
work = subject.associateWith(work);
ExecutorService executorService = new java.util.concurrent.Executors.newCachedThreadPool();
//execute the work on a different thread as the built Subject: executor.execute(work);

案例十四(runable):

Subject subject = new Subject.Builder()...
Runnable work = //build/acquire a Runnable instance.
//associate the work with the built subject so SecurityUtils.getSubject() calls works properly: work = subject.associateWith(work); Executor executor = new java.util.concurrent.Executors.newCachedThreadPool(); //execute the work on a different thread as the built Subject: executor.execute(work);

转载于:https://www.cnblogs.com/telwanggs/p/7608242.html

Shiro的subject实质上是当前执行用户的特定视图。相关推荐

  1. 会计电算化的过程 实质上是用计算机,会计电算化的过程,实质上是用计算机()的过程。A.单一地替代手工会计操作B.单一地替代对会计进行分...

    会计电算化的过程,实质上是用计算机()的过程.A.单一地替代手工会计操作B.单一地替代对会计进行分 更多相关问题 以下对冷饮操作要求描述错误的是:() 客舱网路的功用.() 次高速减脂过程中一般每减多 ...

  2. Shiro RememberMe 1.2.4 反序列化命令执行漏洞复现 kali docker

    Shiro RememberMe 1.2.4 反序列化命令执行漏洞复现 漏洞环境搭建 漏洞复现 反弹shell 题外话1 题外话2 影响版本:Apache Shiro <= 1.2.4 漏洞产生 ...

  3. 在 ubuntu 20.04 LTS 上安装 ROS2 执行 rosdep update 命令时出现的问题的解决办法

    在 ubuntu 20.04 LTS 上安装 ROS2 执行 rosdep update 命令时出现的问题的解决办法 1.sudo rosdep init 在执行 sudo rosdep init 命 ...

  4. Linux系统上Crontab定时执行教程

    Linux系统上Crontab定时执行教程 常用格式示例 每五分钟执行  */5 * * * * 每小时执行     0 * * * * 每天执行        0 0 * * * 每周执行      ...

  5. PowerShell说“此系统上的脚本执行被禁用。”

    我正在尝试运行一个从cmd.exe调用powershell脚本的cmd文件,并且出现以下错误: 无法加载Management_Install.ps1因为在此系统上禁用了脚本的执行. 我跑了 Set-E ...

  6. plc是一台专用计算机对,PLC其实质上是一台工业控制用的专用计算机,它由硬件系统和软件系统两大部分组成...

    参考答案如下 实质上合理地定位服务人群和深入理解服务对象是开发征信分析模型乃至开展征 一切从实际出发,台用的硬件说到底就是要做到: 工业能够产生旋转模糊效果的滤镜是 ( ). 控制润滑系中机油滤清器旁 ...

  7. mappedBy和JoinColumn实质上指向的是同一个表即外键作为主键所在的表对应的实体

    只有双向的时候使用mappedBy mappedBy和JoinColumn实质上指向的是同一个表即外键作为主键所在的表对应的实体(其对应对象1) mappedBy对应实体的声明对象1 JoinColu ...

  8. c语言中保存字符串实质上是,在C语言中,保存字符串“B”实质上是保存字符B和\0两个符号。...

    在C语言中,保存字符串"B"实质上是保存字符B和\0两个符号. 中字符字符下列哪个选项不属于授权的事项?() 保存保存四大()之首卢浮宫是人类最伟大的一个建筑. 实质上1889年庆 ...

  9. 痞子衡嵌入式:在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺. 恩智浦 MCU SE 团队近期一直在加班加点赶 SBL 项目 ...

最新文章

  1. wireshark抓包理解TCP的三次握手
  2. 【机器学习】深刻理解决策树-动手计算ID3算法
  3. 城市大脑背后的技术有哪些?
  4. 【Leetocde | 24 】152. 乘积最大子序列
  5. (47)fs创建多级目录
  6. 你的Unity3d代码质量还可以提高200%
  7. 唉,一大早起床遇到脑残的,实在无语!QQ:124316912
  8. ADO:用代码调用存储过程
  9. 高德地图获取经纬度并逆定位获取地理位置名称(原生)
  10. 混合云存储跨云灾备方案之跨云备份
  11. python一个下载小说的简易爬虫
  12. 使用rimraf一秒删除node_modules文件夹【亲测有用】
  13. 数据可视化笔记4 结构数据的可视化图形
  14. matlab抗混叠滤波器,音频抗混叠滤波器设计
  15. 反爬虫原理与绕过实战
  16. Victoria(硬盘检测工具)v4.46F绿色版
  17. 开篇词:为什什么要学习 Spring Boot
  18. 任性杭州,骨感北京——面试汇总
  19. Oracle DataGuard备机出现ORA-00600 [2619]错误的处理思路
  20. 跳槽需要有一份好的简历

热门文章

  1. HDFS小文件问题解决方案
  2. 2021年CBA总决赛第二场预测
  3. php中调行高代码_网页代码如何调整行距
  4. c# 低功耗蓝牙_C#建立从笔记本电脑内部蓝牙4.0到蓝牙低功耗(BLE)外设的流
  5. STM32 利用空闲中断接收数据
  6. python购物程序_Python学习:购物程序
  7. 用winformz时间格式不正确_霜冻不可怕,用生态防寒布正确预防减少损失
  8. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之LED模板驱动程序的改造:设备树
  9. squid 的配置详解 (转)--SeriesI
  10. 6410的系统时钟设置(上)---6410时钟控制逻辑框架分析