WebApi BaseController - 检查用户

WebApi BaseController - Checking User

我有以下 BaseApiController:

public class BaseApiController : ApiController
{
    public readonly Current _current { get; private set; }
}

我所有的 ApiControllers 都继承自这个。

我需要在 ApiControllers 中的所有方法中进行验证,检查传递的 userId 是否与当前 HttpContext.Current.User.Identity.

匹配
[Route("{userId}/cars")]
public HttpResponseMessage GetCars(int userId)
{
    if (userId != _current.UserId)
    {
        return Request.CreateErrorResponse(HttpStatusCode.Forbidden,                     "Unauthorized");
    }
}

有没有办法在 BaseApiController 上执行此操作,这样我就可以避免在所有接收 userId 作为参数的端点上执行此验证?

您可以根据ActionFilterAttribute创建自定义验证属性来实现您的需要。

对于您的情况,它可能如下所示:

public class UserAccessCheckAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var controller = actionContext.ControllerContext.Controller as BaseApiController;
        object requestUserIdObj;

        if (controller != null && actionContext.ActionArguments.TryGetValue("userId", out requestUserIdObj))
        {
            var userId = (int) requestUserIdObj;

            if (userId != controller._current.UserId)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Unauthorized");
            }
        }
    }
}

之后,您可以装饰控制器或需要使用此属性执行用户 ID 检查的特定操作:

[Authorize]
[RoutePrefix("api/Account")]
[UserAccessCheck] //check user id for all actions in controller
public class AccountController : BaseApiController
{
    //....
}

public class ValuesController : BaseApiController
{
    //....
    [UserAccessCheck] //check user id for specific action only
    public IEnumerable<string> Get()
    {
        //...
    }
}

之后,您的操作中不需要额外的代码