Shiro User Manual-Custom Subjects

1. Custom Subject Instances
Shiro在1.0版本添加了一个新的特性,用于在特殊情景自定义subject。

2. Subject.Builder
Subject.Builder可以创建一个匿名,无session关联的Subject实例:

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

默认无参的Subject.Builder将使用应用中存在的SecurityManager。也可以指定 SecurityManager:

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

Subject.Builder提供的其他方法都需要在buildSubject方法之前调用,假设有一个session ID,你想设置到Subject的session上:

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。需要注意的是,这样方式创建的Subject不会自动与应用线程绑定。如果想随处调用SecurityUtils.getSubject(),必须保证Subject与线程已绑定。

3. Thread Association(线程关联)
与线程绑定有三种方式:
1. Automatic Association -- 通过Subject.execute方法执行Callable或Runnable。
2. Manual Association -- 手动绑定或解除。
3. Different Thread -- 通过Subject.associateWith方法将Subject与Callable或Runnable绑定,并使用其他线程执行Callable或Runnable。

3.1 Automatic Association(自动关联)
如果想让Subject与线程暂时性绑定,可以直接通过Subject的execute方法执行Callable或Runnable,线程执行完毕,就解除绑定。
假如在应用启动时,有一些操作需要执行,当执行完后,希望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

也支持Callable:

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

这在框架开发中很有用。比如,Shiro支持Spring的远程调用,这可以保证远程调用被执行:

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


3.2 Manual Association(手动关联)
在某些场景下,比如说使用Shiro进行框架级的集成开发时,就可能需要手动管理ThreadState(Shiro中保证Subject可以在线程执行间随处可用)。需要注意的是,要保证线程执行完后,清除ThreadState:

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


3.3 A Different Thread(使用其他线程方式)
Subject.associateWith方法将Subject与Callable或Runnable绑定,在线程执行期间,Subject被挂起,直到线程执行完后,Subject才可用, 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);

使用Runnable的例子:

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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值