springboot + shiro动态权限

此处不再说明springboot集成shiro相关内容,如有不懂集成的可以搜素相关帖子。
场景:多项目管理中,各个项目分配给同一个账号不同权限,在进行项目切换中权限会统一查询导致权限范围蔓延扩大,需要进行项目级的权限隔离;

1、首先在ShiroConfig中设置ShiroRealm的名称(可以省略,但是建议设置),此处设置后再后续清除缓存时需要用到;

@Bean
public ShiroRealm shiroRealm() {
    ShiroRealm shiroRealm = new ShiroRealm();
    //此处设置缓存信息在缓存中的名称
    shiroRealm.setName("mpm");
    shiroRealm.setCacheManager(cacheManager());
    return shiroRealm;
}

2、在ShiroRealm中对doGetAuthorizationInfo 方法进行改造,需要在查询权限时根据当前的项目进行查询;当然此方法在项目中只触发一次(未清除shiro缓存情况下)

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    UserModel loginModel = (UserModel) principalCollection.getPrimaryPrincipal();
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    if (loginModel.getIsAdmin() != null && loginModel.getIsAdmin()) {
        info.addStringPermission("*:*");
        return info;
    }
    //此处需要提前缓存切换的项目id,否则获取不到当前项目
    //根据项目id查询用户在项目下的角色所属的资源信息
    Long projectId = Long.valueOf((String.valueOf(SecurityUtils.getSubject().getSession().getAttribute("projectId"))));
    List<String> permissionList = new ArrayList<>();
    if (projectId == null) {
        permissionList = this.resourceService.selectResourceByUserId(loginModel.getId());
    } else {
        permissionList = this.resourceService.selectResourceByUserIdAndProjectId(loginModel.getId(), projectId);
    }
    info.addStringPermissions(permissionList);
    return info;
}

3、在前端页面进行项目切换时,请求后台过程中进行权限缓存清除。shiro在进行权限校验时优先查询缓存信息,如没有缓存信息会触发doGetAuthorizationInfo 方法进行初始化后存入缓存中;
在需要清除缓存的类中注入shiro集成的缓存服务,如当前项目集成的是CacheManager;在切换方法中执行清除缓存,如此可以实现动态权限;

//缓存名称的前缀mpm在ShiroConfig中设置 后缀.authorizationCache为shiro默认的后缀名称
//这个方法的用途是清除当前用户的授权缓存信息 SecurityUtils.getSubject().getPrincipals()获取的是当前用户信息对象
cacheManager.getCache("mpm.authorizationCache").remove(SecurityUtils.getSubject().getPrincipals());

如此,大功告成;

发布了8 篇原创文章 · 获赞 5 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章