博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Unity的AOP的符合基于角色的访问控制(RBAC)模型的通用权限设计
阅读量:5924 次
发布时间:2019-06-19

本文共 3359 字,大约阅读时间需要 11 分钟。

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;

运行效果:

本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/archive/2012/01/13/2321896.html,如需转载请自行联系原作者

你可能感兴趣的文章
阅读源码的心得
查看>>
Bacula Fileset资源翻译文档
查看>>
回归的线性模型---偏置-方差分解
查看>>
概率与信息论---边缘概率
查看>>
systemd-journald CPU高
查看>>
Java简单权限系统
查看>>
Linux下的jdk1.5+eclipse+mysql开发环境配置的经验总结
查看>>
一句话说明单点登录实现
查看>>
Node.js 7.0安装体验和示例代码解读
查看>>
MySQL 运行状态监控方法
查看>>
0基础React native学习
查看>>
加载多个配置文件
查看>>
Vmware三大网络之Host-Only
查看>>
阿里云ubuntu12.04下安装使用mongodb
查看>>
JVM系列三:JVM参数设置、分析
查看>>
【Java多线程】定制并发类(三)实现一个基于优先级的Executor类
查看>>
【Android】关于android:divider 的用法
查看>>
PHP框架Yii编码规范
查看>>
运行junitTest出现CreateProcess error=206错误解决方法
查看>>
voip 电话
查看>>