2017-02-20 86 views
1

我正在開發一個項目,其中一些用戶可以扮演角色AdminReader。這些用戶可以看到所有內容,但無法保存/編輯任何數據。如何在執行操作之前驗證用戶角色?

我知道我能做到這樣:

public JsonResult ChangeStatus(int? id) 
{ 
    // AdminReader validation 
    if (base.User.isAdminReader) 
    { 
     return Json(new 
     { 
      Message = "You don't have privileges to alter data.", 
      Success = false, 
     }, JsonRequestBehavior.AllowGet); 
    } 

    // Function code 

但我不希望插入所有項目函數中上面的代碼。

我想我可以裝飾我的方法,就像我們使用[HttpGet]。我也讀過這個SO post

然後我放棄了這個想法。

但後來我發現有關異常處理程序屬性和日誌記錄操作過濾器。

是否有可能以某種方式將public void OnActionExecuting(ActionExecutingContext filterContext)與我的AdminReader驗證相結合?

我不知道這是否是正確的方式去解決我的問題。另外,我不確定它可以真正起作用。這種情況下的最佳做法是什麼?

任何建議,歡迎提前致謝。

+0

您是否想要限制一整套控制器,以便它們只能由一個角色訪問? – BillRuhl

+0

@BillRuhl。假設一個帶有按鈕的表格列表來改變每一行的狀態(這是我的例子)。'AdminReader'可以查看錶列表(控制器中的一個'PartialViewResult'),但不能'ChangeStatus'(在同一個控制器中的'JsonResult')。它幾乎適用於每個控制器,無論是帶按鈕的列表來更改狀態,還是帶有編輯值的按鈕的模式。該視圖是可訪問的,但方法不應該是 –

+2

我會在視圖本身而不是在控制器中嘗試@if(User.Identity.IsAuthenticated &&!User.IsInRole(「AdminReader」)){// render button} 。換句話說,如果用戶的角色是「AdiminReader」,那麼不要渲染按鈕.. – BillRuhl

回答

0

有很多方法可以做到這一點。

是的,的確,屬性只是元數據。但是,MVC框架中的代碼可以識別某些元數據並對其執行操作。例子包括你提到的兩個屬性(ActionFilters和ExceptionFilters),還有AuthorizationFilters,這可能是你真正想要的。

AuthorizationFilters在ActionFilters之前運行,靠近MVC管道的開始處,允許它們在頁面實際呈現之前阻止訪問。但是,如果你不需要這些,你可以在頁面呈現之前使用這一點來完成特定的事情。

儘管如此,你仍然需要在每個頁面上都有代碼來控制用戶根據角色可以做什麼和不可以做什麼。周圍沒有神奇的方法。無論何時您想要控制用戶可以在基於訪問的頁面上執行的操作,都需要在需要進行控制的每個部分執行該操作的代碼。

從您的示例中不清楚您正在嘗試執行什麼操作,因爲來自頁面的返回值通常是要呈現的HTML,但它看起來像要返回某種狀態消息。我不知道如何複製到所有頁面,因爲頁面本身需要渲染。

+0

「AdminReader」能夠訪問:views,partials,table lists,modals,everything,但他們不能保存, ChangeStatus'(如我的問題示例)。 –

0

我不能完全肯定我理解你的問題,很抱歉,如果這是關閉的。但如果你想執行您AdminReader邏輯,你可以編寫自己的自定義屬性,象下面這樣:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute 
{ 
     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      base.OnAuthorization(filterContext); 
      if (filterContext.Result is HttpUnauthorizedResult) 
      { 
       // Perform your unauthorized action here. 
      } 
     } 
} 

而且然後在任何適用的方法上拋出該屬性(或者,如果它適用於所有內容,則可以將其放在整個Controller類上)。像這樣:

// The RoleSettings is a class of constants I defined that just contain strings 
[AccessDeniedAuthorize(Roles = RoleSettings.AdminRole] 
[HttpPost] 
public ActionResult MyEditMethod() 
{ 
    // Perform actions if they are in the AdminRole 
    // If not authorized, it will do whatever you defined above in the 
    // AccessDeniedAuthorizeAttribute 
} 
相關問題