shiro实战系列(二)之入门实战续-阿里云开发者社区

开发者社区> 开发与运维> 正文

shiro实战系列(二)之入门实战续

简介: 下面讲解基于实战系列一,所以相关的java文件获取pom.xml及其log4j文件同样适用于本次讲解。 一、Using Shiro Using Shiro 现在我们的 SecurityManager 已经设置好并可以使用了,现在我们能够开始做一些我们真正关心的事情——执行安 全操作。

下面讲解基于实战系列一,所以相关的java文件获取pom.xml及其log4j文件同样适用于本次讲解。

一、Using Shiro

Using Shiro 现在我们的 SecurityManager 已经设置好并可以使用了,现在我们能够开始做一些我们真正关心的事情——执行安 全操作。   当保护我们的应用程序时,我们对自己可能提出的最为相关的问题是“当前用户是谁”或“当前用户是否被允许做 XXX”。当我们编写代码或设计用户接口时,问这些问题是很常见的:应用程序通常是基于用户的背景情况建立的, 且你想基于每个用户标准体现(保障)功能。因此,对于我们考虑应用程序安全的最自然的方式是基于当前用户。 Shiro 的 API 使用它的 Subject 概念从根本上代表了“当前用户”的概念。

 

几乎在所有的环境中,你可以通过下面的调用获取当前正在执行的用户:

 

    Subject  currentUser=SecurityUtils.getSubject();
        

使用 SecurityUtils.getSubject(),我们可以获得当前正在执行的 Subject。Subject 是一个安全术语,它基本上的意思是 “当前正在执行的用户的特定的安全视图”。它并没有被称为"User"是因为"User"一词通常和人类相关联。在安全 界,术语"Subject"可以表示为人类,而且可是第三方进程,cron job,daemon account,或其他类似的东西。它仅仅 意味着“该事物目前正与软件交互”。对于大多数的意图和目的,你可以把 Subject 看成是 Shiro 的"User"概念。

getSubject()在一个独立的应用程序中调用,可以返回一个在应用程序特定位置的基于用户数据的 Subject,并且在服 务器环境中(例如,Web 应用程序),它获取的 Subject 是基于关联了当前线程或传入请求的用户数据的。  

 

二、现在你拥有了一个 Subject,你能拿它来做什么?  

如果你想在应用程序的当前会话中使事物对于用户可用,你可以获得他们的会话:

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

Session 是一个 Shiro 的特定实例,它提供了大部分你经常与 HttpSessoins 使用的东西,除了一些额外的好处以及一 个巨大的区别:它不需要一个 HTTP 环境!   如果在一个 Web 应用程序内部部署,默认的 Session 将会是基于 HttpSession 的。但在一个非 Web 环境中,像这个简单的教程应用程序,Shiro 将会默认自动地使用它的 Enterprise Session Management。这意味着你会使用相同的 API 在你的应用程序,在任何层,不论部署环境!这开辟了应用程序的新世界,由于任何需要会话的应用程序不必 再被强制使用 HttpSession 或 EJB Stateful Session Beans。并且,任何客户端技术现在能够共享会话数据。

 

三、因此,现在你能获取一个 Subject 以及他们的 Session。如果他们被允许做某些事,如对角色和权限的检查,像“检 查”真正有用的地方在哪呢?

嗯,我们只能为一个已知的用户做这些检查。我们上面的 Subject 实例代表了当前用户,但谁又是当前用户?呃, 他们是匿名的——也就是说,直到直到他们至少登录一次。那么,让我像下面这样做:

if(!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr","vespa");
            token.setRememberMe(true);
            
            try {
                currentUser.login(token);
            } catch (UnknownAccountException  e) {
                // TODO: handle exception
                log.info("there is no user with username of"+token.getPrincipal());
            }catch (IncorrectCredentialsException  e) {
                // TODO: handle exception
                log.info("Password for account"+token.getPrincipal()+"was incorrect");
            }catch (LockedAccountException  e) {
                // TODO: handle exception
                log.info("The account for username"+token.getPrincipal()+"is locked."+"Please contact your adminstrator to unlock it.");
            }
        }
        

比方说,

他们是是谁:

    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("winnebego:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5' .  " +  "Here are the keys - have fun!"); 
        }else {
            log.info("Sorry,you aren't allowed to drive the 'eagle5' winnebago");
        }

 

最后,当用户完成了对应用程序的使用,他们可以注销:

    currentUser.logout();

 

以上代码完全版如下所示:

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.util.Factory;

public class Tutorial {


    

    private static Logger log = Logger.getLogger(Tutorial.class);
    
    public static void main(String[] args) {
    
        
        log.info("My First Apache Shiro Application");
        
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        
        SecurityManager securityManager = factory.getInstance();
        
        SecurityUtils.setSecurityManager(securityManager);
        
        org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();
        
        Session session = currentUser.getSession();
        
        session.setAttribute("someKey", "aValue");
        
        String value = (String) session.getAttribute("someKey");
        
        if(value.equals("aValue")) {
            log.info("Retrieved the correct value!["+value+"]");
        }
        
        if(!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr","vespa");
            token.setRememberMe(true);
            
            try {
                currentUser.login(token);
            } catch (UnknownAccountException  e) {
                // TODO: handle exception
                log.info("there is no user with username of"+token.getPrincipal());
            }catch (IncorrectCredentialsException  e) {
                // TODO: handle exception
                log.info("Password for account"+token.getPrincipal()+"was incorrect");
            }catch (LockedAccountException  e) {
                // TODO: handle exception
                log.info("The account for username"+token.getPrincipal()+"is locked."+"Please contact your adminstrator to unlock it.");
            }
        }
        
        log.info("User["+currentUser.getPrincipal()+"]"+"logged in successfully");
        
        //test a role
        
        if(currentUser.hasRole("schwartz")) {
            log.info("May the schwartz be with you!");
        }else {
            log.info("Hello,mere mortal");
        }
        
        if(currentUser.isPermitted("winnebego:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5' .  " +  "Here are the keys - have fun!"); 
        }else {
            log.info("Sorry,you aren't allowed to drive the 'eagle5' winnebago");
        }
        
        currentUser.logout();
        System.exit(0);
        
    }
}

 

以上是完整的示例说明如下:

从创建工厂加载配置文件shiro.init到创建安全管理器,到获取当前用户,到用sesion保存用户实例。

再到获取用户实例及其获取用户角色及其相应权限

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章