天天看點

基于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;

運作效果:

基于Unity的AOP的符合基于角色的通路控制(RBAC)模型的通用權限設計

代碼下載下傳:

權限.rar
基于Unity的AOP的符合基于角色的通路控制(RBAC)模型的通用權限設計

本文基于

Creative Commons Attribution 2.5 China Mainland License

釋出,歡迎轉載,演繹或用于商業目的,但是必須保留本文的署名

http://www.cnblogs.com/luminji

(包含連結)。如您有任何疑問或者授權方面的協商,請給我留言。

繼續閱讀