2016-11-29 168 views
2

我做了一個自定義的AuthorizeAttribute負責檢查用戶是否有權訪問給定的資源。爲了使通用的,我需要兩個變量傳遞到屬性:將路由參數傳遞給自定義屬性

  1. 所請求的資源類型
  2. 所請求的資源ID

我可以很容易地分辨有人要求其資源類型的屬性,但如何將請求的ID傳遞給屬性?這裏是我的代碼,只有最後一個變量失蹤(標有?):

[System.Web.Http.Authorize] 
[System.Web.Http.RoutePrefix("api/accounts")] 
public class AccountController : ApiController 
{ 
    [AuthorizeIsOwnResource(ResourcesType = ResourcesTypes.Account, ResourceId = ?)] 
    [System.Web.Http.HttpGet] 
    [System.Web.Http.Route("test/{id}")] 
    public ActionResult Test(string id) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.OK); 
    } 
} 

有什麼建議?我想我可以一起刪除屬性參數,並從AuthorizeCore中的HttpContextBase中確定請求的資源類型和ID;但它是我唯一的選擇嗎?

+0

您有答案了。我認爲最好的解決方案是從HttpContextBase訪問控制器和動作名稱。它更乾淨,更容易實施,並且不易出錯。 –

+0

在思考了一下這個問題後,我認爲你是對的。我想我甚至可以從HttpContextBase中提取RouteData。我會在測試後發佈解決方案 – MichaelCleverly

回答

2

好吧。基於道格拉斯甘迪尼的評論,我決定最好的辦法可能是留給屬性來決定請求哪個ID。這是我工作的自定義屬性:

public class AuthorizeIsOwnResourceAttribute : AuthorizeAttribute 
{ 
    public ResourcesTypes ResourcesType { get; set; } 

    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     var httpContext = HttpContext.Current; 
     var claimsIdentity = httpContext.User.Identity as ClaimsIdentity; 
     var routeData = actionContext.ControllerContext.RequestContext.RouteData; 

     switch (ResourcesType) 
     { 
      case ResourcesTypes.Account: 
       return AuthorizeAccount(routeData, claimsIdentity); 
     } 

     return false; 
    } 

    private bool AuthorizeAccount(IHttpRouteData routedata, ClaimsIdentity claimsIdentity) 
    { 

     var id = routedata.Values["id"].ToString(); 
     var accountClaim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == "Resource-" + ResourcesTypes.Account); 
     if (accountClaim == null || accountClaim.Value != id) 
     { 
      return false; 
     } 

     return true; 
    } 
} 

總之:我從actionContext.ControllerContext.RequestContext.RouteData;請求ID直接在我的屬性

0

您可以覆蓋在代碼中ActionDescriptor您AuthorizationContext:

// Summary: 
    //  Initializes a new instance of the System.Web.Mvc.AuthorizationContext class using 
    //  the specified controller context and action descriptor. 
    // 
    // Parameters: 
    // controllerContext: 
    //  The context in which the result is executed. The context information includes 
    //  the controller, HTTP content, request context, and route data. 
    // 
    // actionDescriptor: 
    //  An object that provides information about an action method, such as its name, 
    //  controller, parameters, attributes, and filters. 
    public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor); 


    // Summary: 
    //  Provides information about the action method that is marked by the System.Web.Mvc.AuthorizeAttribute 
    //  attribute, such as its name, controller, parameters, attributes, and filters. 
    // 
    // Returns: 
    //  The action descriptor for the action method that is marked by the System.Web.Mvc.AuthorizeAttribute 
    //  attribute. 
    public virtual ActionDescriptor ActionDescriptor { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the result that is returned by an action method. 
    // 
    // Returns: 
    //  The result that is returned by an action method. 
    public ActionResult Result { get; set; } 
相關問題