【问题标题】:return status code Unauthorized for custom IActionFilter in WebAPIWebAPI 中自定义 IActionFilter 的返回状态代码未经授权
【发布时间】:2012-12-02 18:32:30
【问题描述】:

我正在使用 asp.net WebAPI,我需要创建一个自定义 ActionFilter,它可以快速检查请求 URI 的用户是否实际上应该能够取回数据。

他们已通过基本身份验证获得使用网络服务的授权,并且他们的角色已通过自定义角色提供者进行验证。

我需要做的最后一件事是检查他们是否有权查看他们使用 URI 中的参数请求的数据。

这是我的代码:

public class AccessActionFilter : FilterAttribute, IActionFilter
    {

        public System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>> continuation)
        {

            var result = //code to see if they have permission returns either 0 or 1

            if (result==0) {
               throw new ArgumentException("You do not have access to this resource");
            }
            return continuation();
        }
    } 

目前我只是抛出一个不是我想要的错误,我宁愿返回 System.Net.HttpStatusCode.Unauthorized 但我对我覆盖的方法有点恼火,我并不完全理解它。

我将如何返回该值?

【问题讨论】:

  • 由于不仅缺少授权,而是提供了身份但用户无权访问,因此正确的 HTTP 响应是 403 Forbidden。

标签: asp.net-mvc-4 asp.net-web-api action-filter


【解决方案1】:

你可以设置状态码而不是抛出异常

public class ExecutionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var result = 0;//code to see if they have permission returns either 0 or 1

        if (result == 0)
        {
            actionContext.Response = new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.Unauthorized,
                Content = new StringContent("Unauthorized User")
            };
        }
        base.OnActionExecuting(actionContext);
    }
}

【讨论】:

  • 这是正确的答案✅
【解决方案2】:

您可能最好坚持使用异常,但使用也会返回 Http 状态代码的 HttpResponseException。

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized));

关于这个的好问题here

附言

实现ActionFilterAttribute可能更简单/更干净

public class AccessActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var result = //code to see if they have permission returns either 0 or 1

        if (result==0) 
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized));
        }
        base.OnActionExecuting(actionContext);
    }

}

【讨论】:

  • 这违反了 HTTP 1.1。它说401 error 必须提供WWW-Authenticate 以指示可接受的方案。 ApiController.Unauthorized 有一个参数。幸运的是,这不是 403 Forbidden 的问题。
  • 抛出异常是昂贵的,所以这不是更容易通过发送许多无效尝试并从抛出的HttpResponseExceptions开销对服务器进行负载来攻击服务器吗?或者也许来自多个请求的带宽无论如何都是瓶颈,所以它不会产生重大影响?
  • @BornToCode 像这样的所有异常都将在 HttpControllerDispatcher (chimera.labs.oreilly.com/books/1234000001708/…) 中捕获,这是一个相当简单的尝试捕获,专门寻找 HttpResponseException - 我不确定它们真的可能有多昂贵 - 因为我总是建议在安全带中对其进行测试并测量 - 如果差异会成为问题,我会感到惊讶 - 看看stackoverflow.com/questions/891217/… 以及确定异常是否真的“昂贵”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2014-06-17
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
相关资源
最近更新 更多