ASP.NET MVC 3自定义授权

7
我正在编写一个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)
{
 //...
}

人们认为什么?编写自定义属性是最清晰和最可维护的方法吗?

2个回答

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)
{
    //...
}

当...你抢先一步了 :-/ 当你在线时,我放弃回答任何.NET问题 Darin,eheheh :P非常好的方法 :)将在我项目上使用它! - balexandre
非常好!如果添加一个构造函数来传递“budgetId”参数名称,那就完美了。 - gw0

0
最好将授权/重定向逻辑放入一个ActionFilterAttribute中,因为您正在寻找权限(这些权限基于操作参数,而不仅仅是用户所占用的角色)。
尽管将逻辑重构为仅使用一次的属性可能会变得混乱(具有大量属性)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接