ActionFilter & User Role 控管 Action 權限

現在的專案中,客戶要求能夠在系統中控管會員權限,區分為唯獨和完全控制兩種。之前比較基本做法就是使用 Forms Authentication 作登入,並在需要登入才能使用的 Controller 或是 Action 加入的 [Authorize] 屬性來限制只有已經登入會員才允許進入。

[Authorize]
public ActionResult Create()
{
return View();
}

▲利用 Authorize 屬性作基本登入驗證

 

自訂會員使用 Role 屬性

如果除了會員登入之外還不夠,他必須滿足某些條件才能解開特定 Action 的權限,例如說可能是某些社群的 VIP 會員,可以開啟一般用戶沒辦法使用的功能,或是像是這次專案遇到的,必須設定更詳細的權限規範等級。那可以選擇來使用 Role 這個屬性來配合控管,但是自訂的角色在 Forms Authentication 沒有預設可以直接寫入 Role 的方法,需要繞一點路來達到。(參考保哥這篇文章)這樣就可以和原本一樣的方式去增加 Action 或是 Controller 的屬性來限制驗證。

[Authorize(Roles = "Full Control")]
public ActionResult Create()
{
return View();
}

▲利用 Roles 來做進一步的權限控管

 

集中管理特定 Action 的權限

加入 Roles 之後其實已經可以針對每一個 Action 去做管理了,但是一整個專案 Action 這麼多,光是 Controller 就數十個了,我嘗試用 Ctrl + F 去找尋要加入 Full Control Roles 的部分,過五分鐘我就放棄了。光的時間太多,而且之後要是有其他變動維護起來也不容易。要加入 Full Control Roles 的部分其實有跡可循,因為在專案之前 Action 的命名還蠻統一的,主要就是 Index,List,Create,Edit,Delete 這幾個部分,當然有些 controller 為了要支援比較特殊的方法命名會不太一樣,但是用特定關鍵字就能夠包括全部。

所以在這邊用了 Action Filter 的擴充方法去做到想要的功能,因為在專案中有用 baseController 去當作全部 Controller 的 Base Class 我就直接將擴充的方法作在 BaseController 裡面,不然也可以選擇用 Global Filter 的方式來做。

protected override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.RouteData.Values["action"].Equals("Edit") ||
filterContext.RouteData.Values["action"].Equals("Create") ||
filterContext.RouteData.Values["action"].Equals("Delete"))
{
if (!HttpContext.User.IsInRole("Full Control"))
{
filterContext.Result = View("AccessDeclined");
}
}
base.OnAuthorization(filterContext);
}

▲集中管理 Action 的部分,將 Edit,Create,Delete Action 限制 Full Control Role

 

這樣做在管理程式碼上面會變得比較容易,這部分需求有變動也不會手忙腳亂的,利用 filterContext 可以取得更多資訊,甚至於把權限控管這一塊全部利用資料庫來設定也是可以。

Reference

概略解釋 Forms Authentication 的運作

http://blog.miniasp.com/post/2008/02/Explain-Forms-Authentication-in-ASPNET-20.aspx

ASP.NET 自訂角色的方式(不用實做 Role Provider)

http://blog.miniasp.com/post/2008/06/11/How-to-define-Roles-but-not-implementing-Role-Provider-in-ASPNET.aspx

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *