前文《做程序员到现在踩过的坑》里我提到了角色权限管理,算算到现在自己已经在两家公司做过3个权限管理模块了,现在简单总结一下;当然本人半路出家,如果写的有什么不对的地方,请留言批评指正。
首先是角色权限管理模块的表设计:按照rbac模式画的,很粗糙(完整的就不上传了,不想收到前公司的传票),可以耦合其他业务需求如多租户多应用等。
这项目是用于客户接入管理权限的一个后台系统,就是客户需要权限管理但不想自己写个系统管理,可以把用户,角色,权限信息在该项目管理,自己的第三方系统直接调该系统即可实现角色权限管理。所以其实该系统本质上就是对用户,角色,权限的一个管理系统。功能就是用户,角色,权限的crud及其关系的建立如为角色授予权限,为用户授予角色和为用户直接授予权限等等。
项目使用OAuth2和shiro管理本系统权限。说到这里挺惭愧的,两家公司写了3个权限管理居然没有去深入研究shiro和SpringSecurity这两个著名的权限管理框架,实在太差了。
重点讲一下后面两个自己写的采用切面实现的权限管理模块,当然不是我一个人的功劳,本来同事写的aop然后换我维护了.
同事是领域驱动设计的大佬,代码风格参考 https://github.com/citerus/dddsample-core ;这两个权限管理耦合大量的业务原因所以不是单纯的上文的rbac权限管理模型。基本思路是自定义权限注解,aop切面判断当前用户是否有注解标记的唯一权限短语(即resource_key),代码如下:
1.Controller方法上打上自定义权限注解:
2.自定义注解与解析:
3.aop切面:
4.鉴权实现:SpecificPermissionCollection是同事封装的权限集合这里其实用containsAll即可,当然这样就没法实现or权限的功能了(就是有权限集合中任意一个权限即可通过验证,据说SpringSecurity集成了权限or的功能),而是必须包含才能通过验证。
其他的用户,角色,权限crud不用我贴了吧,以上基本是精华了,当然对于授予用户角色,角色授予权限,用户额外授予权限有多种实现方式了,这里我是在角色授予权限时先删除该角色下全部权限关系再重新创建角色权限关系的,如下:
授予用户角色就简单多了,关系表里该用户已经有角色就修改,没有就创建;
用户额外授予权限:这个我做过两种方式,这里讲一下大概思路具体就不讲了,一种是直接建立用户和权限的关系表,另一种是每个人额外授权时建立一个隐含角色,该隐含角色不显示,额外授权时直接授予隐含角色。
哦对了,上文讲过遇到过一个坑导致辛苦写了2个星期的权限管理要重写,就是权限范围控制的问题,后来采用权限短语拼接的办法解决的。举个例子,一个用户只有查看操作公司管理里A公司信息的权限而没有其他公司的查看操作权限,那怎么进行权限控制呢?首先数据库里权限短语肯定是有几个公司就有几条权限,比如company_power_A,company_power_B....;在注解里打上权限短语的前半部分company_power,然后切面从传参中取后面的A,B...拼上去组成完整的权限短语(这里要注意和前端约定好传参方式与参数名并保证鉴权的资源与查看操作的资源是同一资源)这种方式比较笨,其实我是比较倾向于权限最好不要耦合业务的,而且最好抽出来单独做成微服务,但既然要求这样写,那也没办法,老实写呗,目前已经重复写两遍了,估计以后还会再重复写。有兴趣的可以去看看这篇文章非常不错,Shiro+JWT+Spring Boot Restful简易教程 https://www.jianshu.com/p/f37f8c295057