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
转载于:https://www.cnblogs.com/luminji/archive/2012/01/13/2321896.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110484.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...