基于Unity的AOP的符合基于角色的访问控制(RBAC)模型的通用权限设计
AOP的特性使得它非常适合用来设计类似权限控制的功能,这是本文的基础,如果想要了解AOP的实现,可以参考《动态织入的AOP实现》。
在基于角色的访问控制(RBAC)中,有三要素:用户、角色、任务(或操作)(User、Role、Task),其稳定性逐渐增强,两个关系,User<->Role、Role<->Task,其中:
- User 是日常管理运行时建立
- Role 是部署/交付建立
- Task 是开发时确定
- User<->Role 是日常管理运行时建立
- Role<->Task 是部署/交付时建立
在本例中,针对Task和Role,我们设计如下的两个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [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,它当前不具备任何权限;
以上的关系描述,我们在代码当中模拟如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | //模拟系统总共有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; } } |
权限判断在切面部分,简化如下(可以看到是判断当前用户是否具有相关权限):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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(); } } |
调用方代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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;
运行效果:
代码下载:权限.rar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器