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

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

你可能感兴趣的:(unity)