为了账号安全,请及时绑定邮箱和手机立即绑定

Easy.Admin 的权限管理

标签:
C#

Easy.Admin 的权限管理

原理

  • 本着先实现再完善优化的原则,就不新造轮子了,而是直接使用 NewLife.XCode自带的权限管理功能,下面详细介绍

  • 从代码层面来讲,就是记录一个角色与一个控制器和控制器所有方法的关系。举个例子,管理员角色拥有用户控制器中添加用户、删除用户等方法的访问权限。假设一个控制器对应一个菜单,控制器的方法就是菜单的操作,这里用户菜单的 id 设为 1,添加用户这个操作标记为 1,删除用户操作标记为 2,更新用户操作标记为 4,依次类推标记所有操作为 2 的 n 次方

  • 当然用什么标记可以自己定,这里只是让他们组成的列表符合位域的设计,即 2 的幂(即 1、2、4、8 等)。记录方式实际上就是将用户 id(这里设管理员 id 为 1)、菜单 id、操作标记、是否授权等这个几个属性记为一条数据。每次访问的时候,就根据当前用户和访问的菜单和操作,查询是否有授权,即可实现权限管理功能

  • 比如,管理员角色对于用户菜单的添加、删除、更新操作,具有权限访问,这些数据记录为

    角色 id 菜单 id 操作 id 是否授权
    1 1 1
    1 1 2
    1 1 4
  • 当使用位域的方式记录所有操作时,比如同时授权添加、删除、更新这三个操作,那么就是1+2+4 = 7,二进制即001 + 010 + 100 = 111,也即1|2|4 = 7,每添加一个操作,直接用当前记录值和操作标记进行或运算。因为每个操作标记对应的二进制都是只有一个 1,而且位置不同,所以加起来不会产生进位,结果相当于累加(没有进位)。那么上述表记录变成

    角色 id 菜单 id 操作 id
    1 1 7
  • 那么怎么知道哪个操作被授权了呢?哪个位置上是 1 就说明哪个操作被授权。而判断方法就是与运算,需要判断的操作和记录值进行与运算,两个位置都是 1 的,结果对应位置才是 1,其余位置都是 0。比如,判断删除操作是否被授权,2 对应二进制 10,和记录值 7 的二进制 111 进行与运算,结果得 010。但如果,10 不在记录值里面,即 101,那么与运算结果为 0。2 & 7 = 2 -> 10 & 111 = 1010 & 101 = 0

  • 总的来说就是,添加操作就是或运算,判断操作就是与运算,那去掉操作呢?那也简单,实际上直接减去就行,对应的二进制运算叫做异或,也叫半加运算,没有进位的加法。比如111 ⊕ 10,10 加上去之后没有进位,结果是 101,相当于去掉了操作,大部分高级语言用的异或符号是^

使用

  • 上面原理说起来也简单,说白了就是两个二进制操作,使用位域把记录简化。后来实际应用的时候,就将一个角色的所有菜单的操作权限全部合在一起,作为角色的一个字段,这个字段的值类似于1#255,2#255,3#255,4#255。设这个字段为Permission,逗号分隔每个菜单,每个记录是菜单id#操作记录值。上述值就是 1-4 这个几个菜单的操作值,都是 255,即1|2|4|8|16|32|64|128,默认可容纳 8 个操作
  • 那么如何将控制器与菜单和操作关联起来呢? NewLife.XCode还提供了扫描控制器的代码,使用时通过在方法添加特性(注解)标记这个方法,代码就会通过反射将每个控制器生成一个菜单,方法生成对应菜单的操作,并记录标记值
  • 权限判断的时候,也是通过这个特性(注解)获取当前方法的操作标记值,找到对应的菜单,再比较操作值
  • 代码详见:

总结

  • 对于一些复杂的权限设计,或者比较精细,那么自己写代码实现才是最好的选择,通用的权限设计毕竟只是满足大众需求
  • 实用至上为原则,只要能很好解决你的问题,那它就是好的解决方案
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消