首页 > 代码库 > (转)shiro权限框架详解05-shiro授权

(转)shiro权限框架详解05-shiro授权

http://blog.csdn.net/facekbook/article/details/54910606

本文介绍

  • 授权流程
  • 授权方式
  • 授权测试
  • 自定义授权realm

授权流程

开始构造SecurityManager环境subject.isPermitted()授权securityManager.isPermitted()执行授权Authorizer执行授权Realm根据身份获取资源权限信息结束

授权方式

Shiro支持三种方式的授权:

  • 编程式:通过写if/else授权代码块完成。
Subject subject = SecurityUtils.getSubject();if(subject.hasRole("admin")){//有权限}else{//没有权限}

 

  • 注解式:通过在执行的Java方法上放置相应的注解完成。
@RequiresRole("admin")public void hell(){//有权限}

 

  • JSP标签:在Jsp页面通过相应的标签完成:
<shiro:hasRole name="admin"><!--有权限--></shiro:hasRole>

 

授权测试

创建ini配置文件

在classpath路径下创建shiro-permission.ini文件,内容如下:

[users]#用户zhangsan的密码是123,此用户具有role1和role2两个角色zhangsan=123,role1,role2lisi=123,role2[roles]#角色role1对资源user拥有create、update权限role1=user:create,user:update#角色role2对资源user拥有create、delete权限role2=user:create,user.delete#角色role3对资源user拥有create权限role3=user:create

 

在ini文件中用户、角色、权限的配置规则是: 用户名=密码,角色1,角色2 、角色=权限1,权限2。首先根据用户找角色,再根据角色找权限,角色是权限集合。

权限字符串规则

权限字符串的规则是:”资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,”:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。 
例子: 
用户创建权限:user:create或user:create:* 
用户修改实例001的权限:user:update:001 
用户实例001的所有权限:user:*:001

测试代码

    @Test    public void testPermission() {        // 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");        // 通过工厂创建SecurityManager        SecurityManager securityManager = factory.getInstance();        // 将SecurityManager设置到运行环境中        SecurityUtils.setSecurityManager(securityManager);        //创建一个Subject实例,该实例认证需要使用上面创建的SecurityManager        Subject subject = SecurityUtils.getSubject();        //创建token令牌,账号和密码是ini文件中配置的        //AuthenticationToken token = new UsernamePasswordToken("zhangsan", "123");//账号密码正确token 角色是 role1,role2        AuthenticationToken token = new UsernamePasswordToken("lisi", "123");//lisi账号的token 角色是role3        /**         * role1=user:create,user:update           role2=user:create,user.delete           role3=user:create         */        try {            //用户登录            subject.login(token);        } catch (AuthenticationException e) {            e.printStackTrace();        }        //用户认证状态        Boolean isAuthenticated = subject.isAuthenticated();        System.out.println("用户认证状态:"+isAuthenticated);//输出true        //用户授权检测        //是否拥有一个角色        System.out.println("是否拥有一个角色:"+subject.hasRole("role1"));        //是否拥有多个角色        System.out.println("是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));        //检测权限        try {            subject.checkPermission("user:create");        } catch (AuthorizationException e) {            e.printStackTrace();        }        try {            subject.checkPermissions("user:create","user.delete");        } catch (AuthorizationException e) {            e.printStackTrace();        }    }

 

基于角色的授权

//是否拥有一个角色System.out.println("是否拥有一个角色:"+subject.hasRole("role1"));//是否拥有多个角色System.out.println("是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));

 

对应的check方法:

subject.checkRole("role1");subject.checkRoles(Arrays.asList("role1","role2"));

 

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException: Subject does not have role [.....]

 

基于资源授权

System.out.println("是否拥有某个权限:"+subject.isPermitted("user:create"));System.out.println("是否拥有多个权限:"+subject.isPermittedAll("user:create","user.delete"));

 

对应的check方法:

subject.checkPermission("user:create");subject.checkPermissions("user:create","user.delete");

 

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [....]

 

自定义realm

在shiro认证那篇博客中编写的自定义realm类中有一个doGetAuthorizationInfo 方法,此方法需要完成:根据用户身份信息从数据库查询权限字符串,由shiro进行授权。

realm代码

/*** 授权方法*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        //后去身份信息,这个字段就是前面的username    String username = (String)principals.getPrimaryPrincipal();    //模拟通过身份信息获取所有权限    List<String> permissions = new ArrayList<>();    permissions.add("user:create");    permissions.add("user:delete");    //将权限信息封装到AuthorizationInfo中,并返回    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();    authorizationInfo.addStringPermissions(permissions);    return authorizationInfo;}

 

shiro-realm.ini文件

需要使用这个配置文件。

测试代码

同上边的授权测试代码,注意修改ini地址为shiro-realm.ini。

授权执行流程

1、 执行subject.isPermitted(“user:create”) 
2、 securityManager通过ModularRealmAuthorizer进行授权 
3、 ModularRealmAuthorizer调用realm获取权限信息 
4、 ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

该文章涉及的代码

代码地址

(转)shiro权限框架详解05-shiro授权