将路由参数传递给自定义属性

时间:2016-11-29 13:41:11

标签: asp.net-mvc asp.net-web-api2

我已经制作了一个自定义AuthorizeAttribute,负责检查用户是否有权访问给定资源。为了使它成为通用的,我需要将两个变量传递给属性:

  1. 请求的资源类型
  2. 请求的资源ID
  3. 我可以很容易地告诉属性请求了哪种资源类型,但是如何将请求的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);
        }
    }
    

    有什么建议吗?我想我可以一起删除属性参数,并从HttpContextBase中的AuthorizeCore中取消所请求的资源类型和ID;但这是我唯一的选择吗?

2 个答案:

答案 0 :(得分:3)

好的。根据道格拉斯甘迪尼的评论,我认为最好的方法可能是让属性决定请求哪个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

答案 1 :(得分:0)

您可以在AuthorizationContext的代码中覆盖ActionDescriptor:

    // 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; }