我已经制作了一个自定义AuthorizeAttribute,负责检查用户是否有权访问给定资源。为了使它成为通用的,我需要将两个变量传递给属性:
我可以很容易地告诉属性请求了哪种资源类型,但是如何将请求的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;但这是我唯一的选择吗?
答案 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; }