zoukankan      html  css  js  c++  java
  • Shiro的subject实质上是当前执行用户的特定视图。

    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);
     
  • 相关阅读:
    linux samba 配置
    实例解读 linux 网卡驱动
    Linux操作系统的安全管理设置
    找回Linux/Unix下各系统的密码
    CF441E Valera and Number
    CF1175F The Number of Subpermutations 题解
    CF1553 比赛记录
    P5618 [SDOI2015]道路修建 题解
    CF 1530 比赛记录
    AT2063 [AGC005E] Sugigma: The Showdown 题解
  • 原文地址:https://www.cnblogs.com/telwanggs/p/7608242.html
Copyright © 2011-2022 走看看