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

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

转载于:https://www.cnblogs.com/luminji/archive/2012/01/13/2321896.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/110484.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • EVE-NG模拟器教程(二)——模拟器安装

    EVE-NG模拟器教程(二)——模拟器安装上一篇文章已经介绍了如何获取EVS-NG模拟器安装包,同时我们知道EVS-NG提供两种类型的安装包,一种是OVF包,另一种是ISO镜像文件,我们可以根据不同需要选择不同类型的安装包,这里我们已经把最新的两种类型的安装包都准备好了,如下,EVE-COMM-VM-112为OVF包,EVE-20171007为ISO镜像文件:接下来就分别介绍一下这两种类型安装包的使用场景和使用方法。一、通过OVF包安装EVS-NG模拟器…

    2022年5月29日
    43
  • 漫步数理统计二十六——多元正态分布

    漫步数理统计二十六——多元正态分布本片博文介绍多元正态分布,我们以nn维随机变量为主,但给出n=2n=2时二元情况的一些实例。与上篇文章一样,我们首先介绍标准情况然后扩展到一般情况,当然这里会用到向量与矩阵符号。考虑随机向量Z=(Z1,…,Zn)′\mathbf{Z}=(Z_1,\ldots,Z_n)^\prime,其中Z1,…,ZnZ_1,\ldots,Z_n是独立同分布的N(0,1)N(0,1)随机变量,那么对z∈Rn,Z\ma

    2025年7月31日
    4
  • js网页特效

    js网页特效br 我平时特别喜欢研究网页特效 这里是平时 截流 下来的几个 JavaScript 网页特效 在此跟大家一起分享 br 反续排列 br 代码 在需要处加入 br nbsp br bdodir rtl 反续列 br 特点 当你需要把一段话反起来排列时 你怎么办呢 反起来一个一个地输入吗 只要使用以上代码 即可实现 br 自动刷新 br 代码 在网页的和之间加入 br metahttpequi refresh content

    2026年1月19日
    1
  • 从控制台读取password – C#

    从控制台读取password – C#

    2022年1月15日
    52
  • NVL()函数

    NVL()函数NVL()函数是Oracle中的一个函数,NVL()函数的功能是实现空值的转换。NVL()函数的功能是实现空值的转换。例如NVL(string1,replace_with)中:当第一个参数(string1)为空时,返回第二个参数(replace_with);当第一个参数(string1)不为空时,则返回第一个参数(string1)。NVL()函数的第一个参数和第二个参数类型必须相同,或…

    2022年7月13日
    17
  • 磁盘,硬盘,软盘,光盘的区别[通俗易懂]

    磁盘,硬盘,软盘,光盘的区别[通俗易懂]计算机存储器分为两大类:内存存储器和外部存储器(简称内存或内存条和外存)。内存容量小,存取速度快,只能临时保存信息(经cup处理后的数据),断电后信息就会消失。外存容量大,存取速度比内存慢,能永久

    2022年8月3日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号