shiro用法笔记

来源:互联网 发布:vb6数据库实例 贴吧 编辑:程序博客网 时间:2024/06/11 07:37

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 somewhereSubject subject = new Subject.Builder(securityManager).buildSubject();

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

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

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

Object userIdentity = //a long ID or String username, or whatever the "myRealm" requiresString 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 subjectsubject.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 subjectMyResult 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);
原创粉丝点击