在我的逻辑层中,我需要检查各种操作的权限。有些行为是通用的,但有些是高度专业化的。每个操作都有一个相应的权限层次结构,在执行操作之前对其进行评估。我一直在琢磨我的脑海中的建筑思想,但还没有达到一个我认为可扩展,简单和优雅的坚实的想法。
当前代码如下所示:
public class LogicObject
{
public void Add()
{
Check Add Permission
Perform
}
public void Update()
{
Check Update Permission
Perform
}
}
这种架构的问题在于,首先它并非真正具有可扩展性,其次它不允许我在不执行操作的情况下检查权限。
我的另一个想法是拥有这样的东西:
public class AddAction : IAction
{
public bool IsPermitted;
public void Perform();
}
public class LogicObject
{
public IAction AddAction {get { return new AddAction(); } }
}
我更喜欢这种架构,但我对此并不十分熟悉。看起来有点好玩。我无法想象这种类型的架构是独一无二的。有哪些更好的方法可以做到这一点?
答案 0 :(得分:4)
您拥有的另一个选择是使用面向方面编程从服务中获取外部组件来控制方法访问权限。它基本上意味着你的方法将在运行时被执行授权的代码包装。
为Java实现此功能的示例解决方案是Spring Security,它将为您提供多种方法来自定义和定义授权方案。 然后该对象看起来像:
public class logicObject {
@PreAuthorize("hasRole('ROLE_USER')")
public void update() {
//Perform
}
//...
}
当然,您需要额外的代码来定义安全上下文,并为具有该上下文的logicObject类创建代理,并定义您的授权本身。
由于您提供的代码示例似乎是在C#中,您可能需要查看基于角色的安全性以及[System.Security.Permissions] [2]命名空间中的所有商品。它允许您使用属性来控制方法在运行时的访问。您可以定义自己的自定义属性和授权提供程序。使用它可能看起来像:
public class LogicObject
{
[PrincipalPermissionAttribute(SecurityAction.Demand, Role="ROLE_USER")]
public void Add()
{
//Perform
}
}
答案 1 :(得分:1)
看起来你在这里使用C#样式,所以一个可能的.Net方法来解决问题的方法是使用你的例子将一个属性附加到定义执行方法所需权限的方法:
public class LogicObject
{
[PrincipalPermission(Security.Demand, Role="AddItem")]
public void Add()
{
Perform
}
[PrincipalPermission(Security.Demand, Role="AddItem")]
public void Update()
{
Perform
}
}
PrincipalPermission检查Thread.CurrentPrincipal用户以查看用户是否拥有相关操作的权限。我还构建了具有类似功能的自定义属性,但更多地处理行级安全性而不是一般权限或权限。
使用属性的优点是你可以编写一次代码,代码适用于属性的每个使用者,而不是一遍又一遍地编写逻辑。
答案 2 :(得分:0)
我认为你的第一个例子并不遥远;我将逻辑分成两半:将外部可见的类成员作为外观 - 与实际完成工作的内部(私有成员)分开。因此,外部门面工作是进行功能调用,执行安全检查并适当地做出响应。这也意味着您对安全检查的执行地点采取了一致的方法。
您可能需要考虑的另一个选项是Microsoft Enterprise Libraries,因为它们具有涵盖此类事物的安全块。你可以免费获得一个安全框架(如果你在MS阵营中,它很有可能是一个很好的选择),并且会有一些示例代码可以详细介绍你的问题。
我不确定扩展文档的位置:Tom Hollanders博客可能是一个值得关注的地方,否则您可以从CodePlex获取EntLibs。