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

Shiro的subject实质上是当前执行用户的特定视图。的更多相关文章

  1. 自动化运维,远程交互从服务器A上ssh到服务器B上,然后执行服务器B上的命令。

    第一种: ftp -v -n 192.168.0.1 21 <<! user ftp ftp123 bay ! 第二种: { echo -e "\n" echo -e ...

  2. Maven依赖中的scope详解,在eclipse里面用maven install可以编程成功,到服务器上用命令执行报VM crash错误

    Maven依赖中的scope详解 项目中用了<scope>test</scope>在eclipse里面用maven install可以编译成功,到服务器上用命令执行报VM cr ...

  3. 工作流JBPM_day02:3-预定义的活动1_4-预定义的活动2+在图片上高亮显示正在执行的上活动

    工作流JBPM_day02:3-预定义的活动1 工作流JBPM_day02:4-预定义的活动2+在图片上高亮显示正在执行的上活动 活动 Activity 预先定义好的活动 Start开始活动 End结 ...

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

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

  5. python paramiko实现ssh上传下载执行命令

    paramiko ssh上传下载执行命令 序言 最近项目经常需要动态在跳板机上登录服务器进行部署环境,且服务器比较多,每次完成所有服务器到环境部署执行耗费大量时间.为了解决这个问题,根据所学的执行实现 ...

  6. Oracle DB 执行用户管理的备份和恢复

    • 说明用户管理的备份和恢复与服务器管理的备份和恢复 之间的差异 • 执行用户管理的数据库完全恢复 • 执行用户管理的数据库不完全恢复 备份和恢复的使用类型 数据库备份和恢复的类型包括: • 用户管理 ...

  7. SQL 禁止在 .NET Framework 中执行用户代码。启用 "clr enabled" 配置选项

    注:本文摘自:http://blog.csdn.net/heshengfen123/article/details/3597125 在执行SQL脚本过程中如果出现 禁止在 .NET Framework ...

  8. 修改php执行用户,并使其拥有root权限

    useradd apachephp vi /etc/httpd/conf/httpd.conf 将组和用户修改成apachephp,重启apache,然后用lsof -i:80查看apache的执行用 ...

  9. Dajngo——10 请求与响应 文件上传 GET和POST请求 类视图

    Dajngo——10 HttpRequest对象 HttpResponse对象及子类 form标签中的GET和POST GET提交方式 POST提交方式 request得GET和POST属性 文件上传 ...

随机推荐

  1. 理解ValueStack的基本机制

    ValueStack基础:OGNL(Object Graphic Navigation Language) OGNL是Struts2中使用的一种表达式语言.它可以用于:   · 在JSP页面,使用标签 ...

  2. [NOI2018] 归程 可持久化并查集

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个n 个节点.m 条边的无向连通图(节点的编号从 1至 n).我们依次用 l,a描述一条边的长度.海拔. ...

  3. XMU 1612 刘备闯三国之桃园结义 【二分】

    1612: 刘备闯三国之桃园结义 Time Limit: 1000 MS  Memory Limit: 128 MBSubmit: 181  Solved: 12[Submit][Status][We ...

  4. 以太坊客户端geth的基本操作命令

    以太坊客户端geth的基本操作命令搭建了私有链环境之后,整理了一下客户端的一些基本的操作命令: 启动命令重复上篇博客步骤,先将区块链客户端启动,命令如下: geth –datadir “%cd%\ch ...

  5. 比特币客户端Electrum使用介绍

    简介 比特币的客户端很多,为什么选择Electrum. 首先Electrum真的很轻量,安装马上可以用,不用下载几百G的区块链账本.我之前安装bitcoin核心客户端,这是个完整节点.下载账本都要好多 ...

  6. P3398 仓鼠找sugar 又一次血的教训

    做什么题都要注意数组的大小,不要犯下数组越界的错误(温馨(狠心)提示): 做了好多遍就是不对,原来是[20]的数组,在for下循环1——>20,神奇爆零: 链接:https://www.luog ...

  7. 转:IIS MVC 发布错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容

    访问网址:http://blog.csdn.net/csethcrm/article/details/37820135 有两个地方需要配置: 1.web.config中的节点: <system. ...

  8. 关于使用kafka时对于大数据消息体是遇到的问题

    kafka对于消息体的大小默认为单条最大值是1M. 但是在我们应用场景中, 常常会出现一条消息大于1M, 如果不对kafka进行配置. 则会出现生产者无法将消息推送到kafka或消费者无法去消费kaf ...

  9. jquery ajax post请求实例

    function test(){ $.ajax({ //提交数据的类型 POST GET type:"POST", //提交的网址 url:"testLogin.aspx ...

  10. Linux后门入侵检测工具,附bash漏洞解决方法

    一.rootkit简介 rootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统文件来达到入侵和和隐蔽的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工具和检查手段很难发现 ...