2011-05-13 168 views
7

我寫的ASP.NET MVC 3應用程序,我有很多角色: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) 
{ 
//... 
} 

人怎麼想的?編寫自定義屬性是最乾淨和最可維護的方法嗎?

回答

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

dang ...你打敗了我: - /當你在線時,我放棄嘗試回答任何.NET問題Darin,eheheh:P雖然非常好的方法:)將在我們的項目中使用它! – balexandre 2011-05-13 08:24:58

+0

非常好!通過添加一個用於傳遞「budgetId」參數名的構造函數,它將是完美的。 – gw0 2011-09-02 12:42:12

0

倒不如把授權/重定向邏輯爲ActionFilterAttribute,因爲你正在尋找的權限(其基於動作參數,而不是純粹基於用戶佔據哪個角色)。

儘管將邏輯重構爲只能使用一次的屬性會變得混亂(具有大量的屬性)。