我正在编写一个ASP.NET MVC 3应用程序,我有很多角色:
系统管理员,客户管理员,预算所有者,应用程序所有者
我知道我可以使用[Authorize(Roles =“...”)]属性轻松限制对某些控制器(和操作方法)的访问。
但是,某些授权不仅仅基于角色,而是基于权限。例如,预算所有者应该只能访问分配给其成本中心的预算 - 而不是其他人的预算。
目前我在操作方法中有一些代码来检查:
if(UserCapabilities.CanAccessBudget(budgetId))
{
// get budget and show view
}
else
{
// redirect to index action
}
这开始使我的代码变得混乱并使检查安全成为一场噩梦 - 因为我有许多需要这些不同类型的授权检查的动作方法。
我的想法是写一些自定义属性,我可以使用它来装饰我的动作方法并清理我的代码:
//
// GET: /Budgets/View/1
[CanAccessBudget]
public ActionResult View(int id)
{
//...
}
人们怎么想?编写自定义属性是最干净,最易维护的方式吗?
答案 0 :(得分:15)
您可以编写自定义授权属性:
public class CanAccessBudgetAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (isAuthorized)
{
var request = httpContext.Request;
var budgetId = request.RequestContext.RouteData.Values["budgetId"]
?? request["budgetId"];
var currentUser = httpContext.User.Identity.Name;
return HasPermissionsForBudget(currentUser, budgetId);
}
return isAuthorized;
}
}
然后:
[CanAccessBudget]
public ActionResult View(int id)
{
//...
}
答案 1 :(得分:0)
最好将授权/重定向逻辑放入ActionFilterAttribute
,因为您正在寻找权限(基于操作参数,而不是纯粹基于用户占用的角色)。
尽管将逻辑重构为仅使用一次的属性可能会变得混乱(具有大量属性)。