Shiro安全框架(授权部分)

本文主要介绍Shiro安全框架的授权部分,包括如何判断用户权限、如何为用户赋予角色和权限,以及Shiro提供的不同业务场景下的权限验证。通过示例代码展示了SimpleAuthorizationInfo对象在授权过程中的作用,帮助理解Shiro授权机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       看过我的Shiro认证部分博文的童鞋们一定已经对Shiro安全框架有了一些的认识,关于Shiro框架大致的认证流程,框架内部为我们提供了哪些功能实现,都有了大致的了解,这篇博文主要大致讲解一下shiro授权的部分的具体实现流程,和代码片段。

       授权,顾名思义是判断用户具体的有哪些权限,我们去开发一个系统,首先看来访者有没有访问系统的权限,进入系统的这一方面是认证,而在用户进入了 我们的系统之后,我们的系统会有很多的菜单或者对资源的增删改查操作,并不是所有的用户都能对我们的系统进行所有操作,假设我们是一个商城的小系统,订单的创建,订单的管理,用户的管理都不是所有用户可以操作的,有些账号只拥有查看的权限,而有一些比如admin账号才具有对系统某些核心模块的操作。但是大的流程不会变得是所有的用户在进入系统之前首先是要经过认证,如果都没有通过认证当然就不去判断用户是否具有哪些权限。

  那接下来我就接着上次的认证代码继续写,没看过我上一篇博文的童鞋可以去看一下,

  传送门:https://blog.csdn.net/JavaJieRui/article/details/108465791

       首先,我们调用subject(主体)的 hasRole("admin") 方法,这个方法是用来看主体对象有没有某一个具体的权限,假设我们来看一下主体对象有没有admin的权限:

if (subject.isAuthenticated()) {
            System.out.println(subject.hasRole("admin"));
        }

        结果一定是没有,为什么呢?因为在我们的自定义Realm里没有对用户的权限进行添加,只是在方法中返回了一个null值,因为在调用这个方法的时候他会去找我们自定义Realm中的 doGetAuthorizationInfo 方法,而我们只是返回了一个null值,所以会输出false:

doGetAuthorizationInfo 方法代码片段:

/**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

  输出结果:

可以看到输出结果是false

        那我们如何去做呢?可以看到在上面那个授权的方法代码片段中传入了一个参数,那这个是什么呢?他其实就是一个身份的集合(一个主体可以有多个身份但是只能有一个主身份),我们可以来看一下:

/**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println(primaryPrincipal);
        return null;
    }

在运行测试类看用户是否有admin权限的时候,是不是来这里找这个方法了:

       走了这个方法并且输出了当前用户名,(在日后我们连接了数据库之后拿到了用户的用户名也就可以拿到当前用户的身份和权限信息)那我们怎么赋予这个用户权限呢?其实也很简单,看了我上一篇博文的童鞋一定对SimpleAuthenticationInfo这个对象不陌生,这个对象就是我们做认证的时候将用户名,密码等参数传入在测试类中验证的。在授权的方法中同样有一个对象是SimpleAuthorizationInfo,这个就是用来操作授权的对象,,其实很好记,一个SimpleAuthenticationInfo对象用来认证,一个SimpleAuthorizationInfo用来操作权限,我们可以看到下方截图在.方法的时候有很多的方法可以用,然后为大家上代码片段:

首先我们用addRole方法为他添加一个权限,也就是假设我们在数据库中查到他的身份信息就是admin:

 /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println(primaryPrincipal);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole("admin");
        return simpleAuthorizationInfo;
    }

添加admin权限后,返回这个simpleAuthorizationInfo对象,再来运行一下测试类,可以看到结果变成了true:

那我们可以再次试一下看我们的lisi这个用户有没有super这个角色呢?

if (subject.isAuthenticated()) {
            System.out.println(subject.hasRole("admin"));
            System.out.println(subject.hasRole("super"));
        }

答案是否定的,他并没有super这个角色

   同时可以看到,你每次去查询他的角色权限信息的时候他会去找一次lisi这个用户,所以这样如果多次查询的话对数据库的访问压力也是很大的。

下面是几种情况的代码段:

if (subject.isAuthenticated()) {
            System.out.println("是否具有某个角色==================");
            //角色权限控制
            System.out.println(subject.hasRole("admin"));
            System.out.println(subject.hasRole("super"));
            //多角色权限控制,假设想看一下有哪些角色
            System.out.println(subject.hasAllRoles(Arrays.asList("admin", "user")));
            System.out.println("是否具有其中一个角色====================");
            //是否具有其中一个角色
            for (boolean b : subject.hasRoles(Arrays.asList("super", "admin", "user"))) {
                System.out.println(b);
            }
        }

以下是输出结果,也就是shiro授权部分提供了几种供我们选择的业务场景:

       看当前用户对某一资源模块是否有操作权限,例如,我们来看一下当前用户对user模块有没有所有的操作权限,因为我们没有配所以结果一定是false:

System.out.println("=============权限字符串的访问控制=========");
            //权限字符串的访问控制 资源标识符:操作:资源类型
            System.out.println("权限:"+subject.isPermitted("user:*:*"));//这个意思就是看当前subject有没有整个user模块的所有操作权限

结果:

下面我们在自定义Realm里给当前主体对象一个权限:

//将数据库查询权限信息赋值给权限对象
        simpleAuthorizationInfo.addStringPermission("user:*:01");//这个权限字符串的含义是当前对象只对01用户有所有操作权限

这样的话,结果还是为false,就不测试了,下面我们给当前用户赋予一个所有模块的所有操作权限,再来测试一下结果:

       可以看到上方的截图是true,那么我们再来思考一下,如果在测试类中将权限字符串改为user:create:01,也就是对user模块的01用户进行创建操作会是什么结果呢?答案也是true,因为这里都配了,user:*:*也就是说在user模块中所有的都能通过,我就不为大家测试了,再来打个比方,如果在自定义Realm中我们将权限字符串配为user:create,在user模块中对所有用户进行创建操作,在测试类中配为user:update会为true吗?答案也是否定的,因为我们在自定义Realm中配的是对所有用户的创建操作有权限,而测试类中是更新操作,所以会为false。

再来看一下分别具有哪些权限:

System.out.println("分别具有哪些权限"+"=======================");
            //分别具有哪些权限
            boolean[] permitted = subject.isPermitted("user:*:*", "order:*:*");
            for (boolean b : permitted) {
                System.out.println(b);
            }

看当前主体是否具有用户模块的所有权限,订单模块的所有权限,结果为true,false:

下面是看当前主体对象同时具有哪些权限: 

System.out.println("==============同时具有哪些权限===============");
            //同时具有哪些权限:
            System.out.println(subject.isPermittedAll("user:*:*", "product:*:*"));

结果(false): 

       当前shiro权限的部分就写到这里了,其实权限部分看起来有一些多,内容也有一些杂乱,但是整体还是比较简单的,对有权限的认证还是挺清晰的,主要是根据shiro为我们提供的API来体会整个我们在平时开发中会用到的一些权限认证的几个不同的业务场景,希望能看下来的小伙伴能够体会一下其中不同API的用法和结合自身业务来使用shiro的权限模块。

      在下一篇博文中,我会就shiro安全框架与springboot进行整合,并且连接数据库,不再使用当前demo中的假数据,进一步让大家体会shiro的魅力,谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值