基于Unity的AOP的符合基于角色的访问控制(RBAC)模型的通用权限设计

本文涉及的产品
访问控制,不限时长
简介: AOP的特性使得它非常适合用来设计类似权限控制的功能,这是本文的基础,如果想要了解AOP的实现,可以参考《动态织入的AOP实现》。 在基于角色的访问控制(RBAC)中,有三要素:用户、角色、任务(或操作)(User、Role、Task),其稳定性逐渐增强,两个关系,UserRole、RoleTas...

AOP的特性使得它非常适合用来设计类似权限控制的功能,这是本文的基础,如果想要了解AOP的实现,可以参考《动态织入的AOP实现》。

在基于角色的访问控制(RBAC)中,有三要素:用户、角色、任务(或操作)(User、Role、Task),其稳定性逐渐增强,两个关系,User<->Role、Role<->Task,其中:

  • User 是日常管理运行时建立
  • Role 是部署/交付建立
  • Task 是开发时确定
  • User<->Role 是日常管理运行时建立
  • Role<->Task 是部署/交付时建立

在本例中,针对Task和Role,我们设计如下的两个类:

    [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
    public class TaskAttribute: Attribute
    {

        public TaskAttribute(string taskName, string taskDescription)
        {
            TaskName = taskName;
            TaskDescription = taskDescription;
        }

        public string TaskName { get; set; }
        public string TaskDescription { get; set; }
    }

    public class Role
    {
        public string Name { get; set; }
        public List<TaskAttribute> Tasks { get; set; }
    }

可以看到,Task是继承自Attribute的,源于Task需要和实际的功能接口匹配起来,而Role,则无此需要。

本文演示所需要的权限关系描述如下:

1:系统有4个权限;

2:系统有两个角色,一个叫做Manager,它具有两个权限,另一个角色为Common,它当前不具备任何权限;

以上的关系描述,我们在代码当中模拟如下:

        //模拟系统总共有4种权限
        public static List<TaskAttribute> Tasks
        {
            get
            {
                if (_tasks == null)
                {
                    _tasks = new List<TaskAttribute>()
                                 {
                                     new TaskAttribute("AddItem","增加"),
                                     new TaskAttribute("ModifyItem","修改"),
                                     new TaskAttribute("RemoveItem","删除"),
                                     new TaskAttribute("ListItem","获取列表")
                                 };
                }
                return _tasks;
            }
        }

        private static List<Role> _roles;

        //模拟系统总共有两类角色
        //第一类角色Manager,有增加和修改权限
        //第二类角色Common,没有任何权限
        public static List<Role> Roles
        {
            get
            {
                if (_roles == null)
                {
                    _roles = new List<Role>()
                                {
                                    new Role(){Name = "Manager", Tasks = new List<TaskAttribute>()
                                                                      {
                                                                            new TaskAttribute("AddItem","增加"),
                                                                            new TaskAttribute("ModifyItem","修改")
                                                                      }},
                                    new Role(){Name = "Common", Tasks = new List<TaskAttribute>()}
                                };
                }
                return _roles;
            }
        }

权限判断在切面部分,简化如下(可以看到是判断当前用户是否具有相关权限):

    public class AuthorityHandler : ICallHandler
    {
        /// <summary>
        /// Invoke order
        /// </summary>
        public int Order { get; set; }
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            MethodBase mb = input.MethodBase;
            object[] attrObj = mb.GetCustomAttributes(typeof(TaskAttribute), false);

            if (attrObj == null)
            {
                throw new ArgumentException("TaskAttribute should be defined with the AuthorityAttribute");
            }
            else
            {
                TaskAttribute attr = (TaskAttribute)attrObj[0];
                if (!string.IsNullOrEmpty(attr.TaskName))
                {
                    string taskName = attr.TaskName;
                    //get current user's roles
                    IEnumerable<Role> currentUserRoles = from p in SampleApp.Roles where p.Name == SampleApp.User.Name select p;
                    //if match then return;
                    foreach (Role currentUserRole in currentUserRoles)
                    {
                        IEnumerable<TaskAttribute> tasks = from p in currentUserRole.Tasks
                                                           where p.TaskName == taskName
                                                           select p;
                        if (tasks.Count() > 0)
                        {
                            var retvalue = getNext()(input, getNext);
                            return retvalue;
                        }
                    }
                    //else throw exception
                    throw new UnauthorizedAccessException("access denied");
                }
            }
            return null;
        }
    }

    public class AuthorityAttribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new AuthorityHandler();
        }
    }

调用方代码:

        static void Main() {
            var container1 = new UnityContainer()
                .AddNewExtension<Interception>()
                .RegisterType<IBiz, Biz1>();
            container1
                .Configure<Interception>()
                .SetInterceptorFor<IBiz>(new InterfaceInterceptor());

            SampleApp.User = new User() { Name = "Common" };
            var sample1 = container1.Resolve<IBiz>();
            sample1.AddItem();
            
            Console.ReadKey();
        }

可以看到,使用了Unity来进行AOP;

运行效果:

image

代码下载:权限.rar

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
目录
相关文章
|
3月前
|
安全 数据安全/隐私保护 开发者
|
6月前
|
Kubernetes 数据安全/隐私保护 容器
k8s学习-CKA真题-基于角色的访问控制-RBAC
k8s学习-CKA真题-基于角色的访问控制-RBAC
209 0
|
弹性计算 NoSQL Linux
.Net Core实战之基于角色的访问控制的设计-部署篇
2年前开源了Sikiro.RBAC系统(https://github.com/SkyChenSky/Sikiro.RBAC)但是缺少了部署流程,这次通过申请免费的ECS,重新把流程梳理了下,并整理成改篇文章。 .Net Core实战之基于角色的访问控制的设计(https://www.cnblogs.com/skychen1218/p/13053878.html)
80530 23
.Net Core实战之基于角色的访问控制的设计-部署篇
|
安全 Java 数据安全/隐私保护
Spring Security-内置访问控制方法介绍和角色权限判断
Spring Security-内置访问控制方法介绍和角色权限判断
Spring Security-内置访问控制方法介绍和角色权限判断
|
数据安全/隐私保护
RBAC基于角色的访问控制权限的基本模型
RBAC基于角色的访问控制权限的基本模型
162 0
RBAC基于角色的访问控制权限的基本模型
|
数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计(二)
.Net Core实战之基于角色的访问控制的设计(二)
149 0
.Net Core实战之基于角色的访问控制的设计(二)
|
数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计(三)
.Net Core实战之基于角色的访问控制的设计(三)
160 0
.Net Core实战之基于角色的访问控制的设计(三)
|
SQL NoSQL 前端开发
.Net Core实战之基于角色的访问控制的设计(一)
.Net Core实战之基于角色的访问控制的设计(一)
233 0
.Net Core实战之基于角色的访问控制的设计(一)
|
弹性计算 数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计-
2年前开源了Sikiro.RBAC系统(https://github.com/SkyChenSky/Sikiro.RBAC)但是缺少了部署流程,这次通过申请免费的ECS,重新把流程梳理了下,并整理成改篇文章。 .Net Core实战之基于角色的访问控制的设计(https://www.cnblogs.com/skychen1218/p/13053878.html)
|
弹性计算 数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计-部署篇
2年前开源了Sikiro.RBAC系统(https://github.com/SkyChenSky/Sikiro.RBAC)但是缺少了部署流程,这次通过申请免费的ECS,重新把流程梳理了下,并整理成改篇文章。 .Net Core实战之基于角色的访问控制的设计(https://www.cnblogs.com/skychen1218/p/13053878.html)