您的位置:首页 > 移动开发 > Unity3D

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

2012-01-13 17:38 941 查看
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;

运行效果:





代码下载:权限.rar
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐