2013-10-16 103 views
6

我已經實現了我自己的自定義授權屬性。如何在控制器和操作級別使用Authorize屬性?

該屬性應用於控制器級別和動作級別。

這裏是什麼,我需要做的一個例子:

[ClaimsAuthorize(Roles = "AdvancedUsers")] 
public class SecurityController : Controller 
{ 
    [ClaimsAuthorize(Roles = "Administrators")] 
    public ActionResult AdministrativeTask() 
    { 
     return View(); 
    } 

    public ActionResult SomeOtherAction() 
    { 
     return View(); 
    } 
} 

目前,如果用戶具有管理員角色,但不是AdvancedUsers角色,他就不能執行「管理任務」。

即使用戶未在控制器級別授權,如何更改此行爲以在操作級別執行安全檢查?

目前,我能想到的唯一解決方案是實現2個屬性:一個用於保護控制器,另一個用於保護操作。然後我會玩Order屬性來首先執行動作級別的屬性。

但是,如果可能的話,我寧願使用單個屬性的解決方案。

+1

通過來自控制器級移除。當行動是決定的時候,你爲什麼希望在控制器層面擁有它? –

+0

我還沒有對此進行過測試,但可能通過在行爲**上的自定義授權屬性**之前列出'[AllowAnonymous]'來獲得該行爲的授權。 –

+0

在控制器級別,您可以檢查特定操作方法是否裝有您的特殊屬性,然後允許調用該方法 –

回答

3

要使特定操作受限制,只需在處理這些操作的方法上使用Authorize-attribute。 使用Authorize屬性標記操作方法時,對該操作方法的訪問僅限於經過身份驗證和授權的用戶。

 //[ClaimsAuthorize(Roles = "AdvancedUsers")] 
    public class SecurityController : Controller 
    { 

     { 
     [ClaimsAuthorize(Roles ="Administrators", "Role2","Role3")] 
     public ActionResult AdministrativeTask() 
     { 
      return View(); 
     } 
    } 

或者您可以覆蓋你在控制器級別的授權, 創建一個新的OverrideAuthorizeAttribute屬性。

public class OverrideAuthorizeAttribute : AuthorizeAttribute { 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 
    } 
} 

並且您可以使用此屬性來覆蓋您的控制器級別自動化。

[ClaimsAuthorize(Roles = "AdvancedUsers")] 
public class SecurityController : Controller 
{ 
    [ClaimsAuthorize(Roles = "Administrators")] 
    public ActionResult AdministrativeTask() 
    { 
     return View(); 
    } 
    [OverrideAuthorizeAttribute(Roles ="xxxx")] // This role will override controller     
                //level authorization 
    public ActionResult SomeOtherAction() 
    { 
     return View(); 
    } 
} 
+0

這將授權管理員執行所有其他操作。有些東西,我不希望做... – rlesias

+0

'OverrideAuthorizeAttribute'不適用於我,它實際上並未覆蓋,但控制器級別的角色仍然適用。 –

0

檢查this上一個問題。 (檢查@AndyBrown答案,案例2)

對於您也可以嘗試添加一個簡單的方法( [使用AllowAnonymous])覆蓋控制器 [授權] 然後添加一個新的自定義過濾器來檢查你的邏輯此特定行動。或者你可以在代碼中添加檢查角色的代碼。

+0

@ AndyBrown的解決方案可行,但它涉及到定義2個屬性,這是我想避免的。 – rlesias

+0

然後添加[AllowAnonymous],然後在函數(action)本身中檢查你想要的角色。我認爲這是儘可能簡單的 –

2

這應該是不可能的。想象MVC使用授權過濾器的邏輯。

  1. 確定控制器時 - 檢查是否存在適用於該控制器並執行的授權過濾器。
  2. 當動作已知時 - 對動作執行相同操作。

在任何情況下,授權失敗都會使管道短路。

1

您需要兩個授權屬性 - 一個包含所有授權邏輯的基礎授權屬性,另一個授權屬性源自基礎屬性,僅用於覆蓋基本屬性。

實例授權屬性:

public class ClaimsAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected bool _canOverride = true; 

    //...custom authorization code goes here..... 

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     //Don't authorize if the override attribute exists 
     if (_canOverride && actionContext.ActionDescriptor.GetCustomAttributes<OverrideClaimsAuthorizeAttribute>().Any()) 
     { 
      return; 
     } 
     base.OnAuthorization(actionContext); 
    } 

} 


public class OverrideClaimsAuthorizeAttribute : ClaimsAuthorizeAttribute 
    { 
     public OverrideClaimsAuthorizeAttribute() 
      : base() 
     { 
      _canOverride = false; 
     } 

    } 

在基本授權屬性我們說繼續前進,並授權爲正常,只要OverrideClaimsAuthorizeAttribute不存在。如果OverrideClaimsAuthorizeAttribute存在,則只對_canOverride爲false的類(即OverrideClaimsAuthorizeAttribute類本身)運行授權。

實例:

[ClaimsAuthorize(Roles = "AdvancedUsers")] 
public class SecurityController : Controller 
{ 

    //Ignores the controller authorization and authorizes with Roles=Administrators 
    [OverrideClaimsAuthorize(Roles = "Administrators")] 
    public ActionResult AdministrativeTask() 
    { 
     return View(); 
    } 


    //Runs both the controller and action authorization, so authorizes with Roles=Administrators AND Roles=AdvancedUsers 
    [ClaimsAuthorize(Roles = "Administrators")] 
    public ActionResult AdvancedAdministrativeTask() 
    { 
     return View(); 
    } 

    //authorizes with controller authorization: Roles=AdvancedUsers 
    public ActionResult SomeOtherAction() 
    { 
     return View(); 
    } 
} 
1

使用內置[OverrideAuthorization()]

[ClaimsAuthorize(Roles = "AdvancedUsers")] 
public class SecurityController : Controller 
{ 
    [OverrideAuthorization()] 
    [ClaimsAuthorize(Roles = "Administrators")] 
    public ActionResult AdministrativeTask() 
    { 
     return View(); 
    } 

    public ActionResult SomeOtherAction() 
    { 
     return View(); 
    } 
} 
相關問題