Shiro安全框架(Shiro与SpringBoot整合开发)授权部分(三)权限实现

本文介绍了如何在Shiro安全框架中实现与SpringBoot的整合,特别是授权部分的权限字符串获取。通过分析数据库表结构,编写SQL查询,实现了通过角色ID获取权限信息和URL。接着在自定义Realm中,将权限信息放入simpleAuthorizationInfo,从而实现权限控制。通过示例展示了不同角色对菜单和功能的可见性,体现了细粒度的权限管理功能。

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

之前我们再shiro中已经实现了认证数据的数据库获取,权限数据的数据库获取,最后我们再来看一下有关权限字符串集合的获取,其实权限字符串的获取和角色的获取集合也是大同小异的,下面就可以来看一下这个权限的细粒度的权限控制。

首先我们来分析一下,在数据库中的表:分别是 t_role,t_perms,t_role_perms这三张表,t_role是角色表,t_perms为权限表,t_roler_perms为权限与角色的中间表,那么我们最终的目的就是要通过角色id来获取权限字符串,url,角色名称。

那么想好需要什么,那几张表,这样我们就可以写sql了:

SELECT p.id,p.perms_name name,p.url,r.rolename
FROM t_role r
LEFT JOIN t_role_perms rp
ON r.id = rp.role_id
LEFT JOIN t_perms p
ON rp.perms_id = p.id
WHERE r.id = '#{id}'

这个sql的含义就是通过id来获取权限信息和角色信息以及url,我们再将roleid标为1,查询的结果

编写dao层方法:

    /**
     * 根据角色Id查询权限信息
     * @param Id
     * @return
     */
    List<Perms> findPermsByRoleId(@Param("Id")String Id);

service层方法:

    /**
     * 根据角色Id查询权限信息
     * @param Id
     * @return
     */
    List<Perms> findPermsByRoleId(String Id);

业务层实现类:

    /**
     * 根据角色Id查询权限信息
     * @param Id 角色Id
     * @return
     */
    @Override
    public List<Perms> findPermsByRoleId(String Id) {
        return userDao.findPermsByRoleId(Id);
    }

上面通过角色id获取权限字符串的方法完成了之后,我们接下来就需要去自定义Realm去看一下了,在自定义Realm中我们还需要将权限字符串信息放入到simpleAuthorizationInfo中:

public class MyRealm extends AuthorizingRealm {
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //首先拿到用户的主身份信息
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        //用获取容器中对象的工具类拿到userService对象
        UserService userService = (UserService) ApplicationContextUtils.getBean("userService");
        //授权角色信息、角色集合
        User user = userService.findRolesByUsername(primaryPrincipal);
        //使用CollectionUtils方法判空,如果roles集合非空说明有角色信息
        if (!CollectionUtils.isEmpty(user.getRoles())){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //遍历角色集合之后添加角色字符串
            user.getRoles().forEach(role -> {
                //遍历出每个角色对象,拿到名称
                simpleAuthorizationInfo.addRole(role.getName());
                //调用业务层方法,通过角色id拿到权限字符串信息
                List<Perms> perms = userService.findPermsByRoleId(role.getId());
                //判断权限字符串集合不为空
                if (!CollectionUtils.isEmpty(perms)){
                    //遍历权限字符串集合
                    perms.forEach(perm -> {
                        //拿到每个权限字符对象获取名字属性
                        simpleAuthorizationInfo.addStringPermission(perm.getName());
                    });
                }
            });
            //返回授权信息
            return simpleAuthorizationInfo;
            }

        return null;
    }

在上面的自定义Realm中我们可以看到我们再遍历角色集合的时候,拿到角色对象之后获取角色名称,然后添加角色,同样的,我们在这个方法中调用业务层的对象,通过角色的id获取到了权限字符串的集合,然后遍历这个权限字符串集合之后拿到权限字符串名称,并添加,最终返回权限信息。

这样的话我们可以看一下目前我们的数据库信息,admin是拥有user用户模块的全部权限的,所以在之前我们的admin包括zhangsan用户登录进来是看不到用户模块的下属菜单的,那现在我们可以登录看一下效果:

可以看到,现在我们不论是zhangsan还是admin用户都能展示出来我们的用户管理这个模块的下属菜单。

为了看效果,我们再给admin加一个order:*:*的权限,并且将前端页面的用户修改改为有order权限才能展示,之后再用zhangsan登录看一下效果:

此时用户修改只有拥有order权限才能展示,此时admin用户拥有order:*:*权限,zhangsan没有,首先是admin登录:

可以看到admin还是可以看到所有的菜单,而zhangsan呢?

可以看到,张三并没有用户修改的权限,这就是细粒度的权限控制,权限字符串的简单实现。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值