2013-05-07 35 views
3

我想設置爲我控制器上的方法的默認訪問,所以我加我ApiController[Authorize]屬性。默認授權角色在控制水平和覆蓋的方法

在大多數情況下,除非與[AllowAnonymous]覆蓋屬性能正常工作。

現在我想再添加一個級別。對於我默認的授權方法,我希望他們需要特定角色(例如管理員),因此我將控制器級別屬性更新爲[Authorize(roles="admin")]。除了少數例外,我不在乎它們是什麼角色(只是經過驗證足夠好)。

我想我可以堅持在控制器級別設置Authorize屬性並在個別方法級別覆蓋它,但是這看起來不像[AllowAnonymous]那樣工作。

是否有任何建議,告訴我們怎樣去這個問題,而不必記住裝飾用默認的訪問級別每一個新的方法?像[Authorize(roles="*")]?即使我需要有一個默認的角色用戶是AuthenticatedUsers像一個組成部分,這將是罰款。

回答

7

如何創建標記屬性? AllowAnonymous就是這樣一個標記,BTW。創建您自己的授權屬性並清除角色,當標記出現時。

[MyAuth(Roles = "admin")] 
public class ValuesController : ApiController 
{ 
    [ExemptRoles] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "value1", "value2" }; 
    } 
} 

public class ExemptRolesAttribute : Attribute { } 

public class MyAuthAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     if (actionContext.ActionDescriptor.GetCustomAttributes<ExemptRolesAttribute>().Any()) 
      base.Roles = String.Empty; 

     base.OnAuthorization(actionContext); 
    } 
} 
+0

很好的解決方案。謝謝! – earthling 2013-05-08 18:28:29

1

這裏基本上是我在做什麼。我創建了一個自定義AuthorizeAttribute並覆蓋了OnAuthorization方法。

我就能夠檢查用戶是否是任何標記在當前自定義屬性的角色。
如果不是,我會回到默認授權處理。

public class InternalAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     if(actionContext == null) 
      throw new ArgumentNullException("actionContext"); 
     if (AuthorizeRequest(actionContext)) 
      return; 

     // no special authorization found. fall back to base (handles AllowAnonymous, and Controller level attribute) 
     base.OnAuthorization(actionContext); 
    } 


    private bool AuthorizeRequest(HttpActionContext actionContext) 
    { 
     if (!actionContext.ActionDescriptor.GetCustomAttributes<InternalAuthorizeAttribute>().Any()) 
      return false; 

     foreach (AuthorizeAttribute attribute in actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>()) 
     { 
      foreach (var role in attribute.Roles.Split(',')) 
      { 
       if (HttpContext.Current.User.IsInRole(role)) return true; 
      } 
     } 
     return false; 
    } 
}