简单shiro扩展实现NOT、AND、OR权限验证

编程技术  /  houtizong 发布于 3年前   62

使用过shiro的朋友应该都知道在要想实现any permission的验证是比较麻烦。

 

很多朋友刚开始接触时以为如<shiro:hasPermission name="showcase:tree:*"> 代表验证拥有任何权限,但这是错误的。如果我们把showcase:tree:*授权给用户,那么此时表示用户具有showcase:tree资源的任意权限,如<shiro:hasPermission name="showcase:tree:*">或shiro:hasPermission name="showcase:tree:create">都能验证成功。

 

还有朋友认为<shiro:hasPermission name="showcase:tree:create,update"> 是或的关系,也不是,默认是且的关系。

 

下载了最新的shiro1.3.0-SNAPSHOT 发现并没有增加新的标签或其他支持。

 

因此我们需要简单的扩展下shiro来支持像spring security 3那样的@Secured支持表达式的强大注解。

 

不过有人已经提交了一个基于ANTLR实现的@Secured,可以在其JIRA上找到,在其官网的[ Version 2 Brainstorming ]也介绍并探讨了使用ANTLR语法的@Secured注解,可能在为了shiro 2版本添加进去,估计还得大半年,现在是1.3.0-SNAPSHOT。

 

对于我而言暂时不需要那么复杂的。因此暂时考虑扩展下默认的实现,在不添加任何注解/标签的基础上,简单的支持NOT、AND、OR即可。因此我们扩展AuthorizingRealm,并修改:

 

    private static final String OR_OPERATOR = " or ";    private static final String AND_OPERATOR = " and ";    private static final String NOT_OPERATOR = "not ";    /**     * 支持or and not 关键词  不支持and or混用     * @param principals     * @param permission     * @return     */    public boolean isPermitted(PrincipalCollection principals, String permission) {        if(permission.contains(OR_OPERATOR)) {            String[] permissions = permission.split(OR_OPERATOR);            for(String orPermission : permissions) {                if(isPermittedWithNotOperator(principals, orPermission)) {                    return true;                }            }            return false;        } else if(permission.contains(AND_OPERATOR)) {            String[] permissions = permission.split(AND_OPERATOR);            for(String orPermission : permissions) {                if(!isPermittedWithNotOperator(principals, orPermission)) {                    return false;                }            }            return true;        } else {            return isPermittedWithNotOperator(principals, permission);        }    }    private boolean isPermittedWithNotOperator(PrincipalCollection principals, String permission) {        if(permission.startsWith(NOT_OPERATOR)) {            return !super.isPermitted(principals, permission.substring(NOT_OPERATOR.length()));        } else {            return super.isPermitted(principals, permission);        }    }

 

如上代码即可以实现简单的NOT、AND、OR支持,不过缺点是不支持复杂的如AND、OR组合。

 

这样我就可以像如下使用了,不需要额外的标签,就是太长,如果实现如showcase:tree:(create|update|delete)这种语法相对而言简单多了,希望未来官网支持更好的方式:

<shiro:hasPermission name="showcase:tree:create or showcase:tree:update or showcase:tree:delete">

 

shiro总起来说使用起来还是比较舒服的,就是更新太慢。。。。

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客