【问题标题】:How to create a filter that returns a forbidden result如何创建返回禁止结果的过滤器
【发布时间】:2019-11-26 12:56:36
【问题描述】:

我想创建一个 Web api 过滤器来检查请求标头是否具有正确的 Api 密钥。

如果没有,我想返回 403 响应代码并停止执行(禁止操作)

public class ApiPermission : ActionFilterAttribute
{
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

        }
}

使用 filterContext 我知道我可以执行以下操作:

filterContext.Result = new RedirectTo...

但是如何将状态码更改为 403 并返回一个字符串并暂停执行并停止处理其他过滤器和控制器操作?

【问题讨论】:

  • 你有没有想过这个问题?我也觉得抛出异常是不对的。
  • @JasonBray 看我的回答

标签: c# asp.net-mvc asp.net-web-api


【解决方案1】:

如果您不想抛出异常,可以改为返回 HttpStatusCodeResult

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.Result != null) return;   //Another filter has already returned a result so pass it on

    //Do your filtering

    filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden, "Forbidden");
}

【讨论】:

  • 我找不到 HttpStatusCodeResult。我改用 StatusCodeResult。
  • 此答案适用于 ASP.NET MVC,即 (System.Web.Mvc)。是的,看起来Microsoft.AspNetCore.Mvc.StatusCodeResult 是一种针对 ASP.NET Core 的方法。 ControllerBase 提供了一个 StatusCode 方法作为创建其中之一的快捷方式。我还看到了一个 ForbidResult 类,有趣的是,它没有继承自 StatusCodeResult 我很好奇这是什么原因。
【解决方案2】:

看起来发布的答案与 Asp.Net Core 2.1 不兼容。在核心你可以做类似的事情

filterContext.Result = new  ObjectResult(actionContext.ModelState)
{
    Value = null,
    StatusCode = StatusCodes.Status403Forbidden
};

或者创建像 BadRequest 这样的类可能会很方便,但是对于 403 代码。

public class ForbiddenObjectResult : ObjectResult
{
    public ForbiddenObjectResult(object value)
            : base(value)
    {
        StatusCode = StatusCodes.Status403Forbidden;
    }
}

...

filterContext.Result = new ForbiddenObjectResult(filterContext.ModelState);

【讨论】:

    【解决方案3】:

    在 .NET core(我使用的是 3.0)中,您可以通过在操作过滤器中使用以下内容来确保代码不会随后到达控制器操作:

     filterContext.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
    

    【讨论】:

      【解决方案4】:

      你可以抛出一个HttpException,它可以让你传递任何 HTTP 代码并停止执行(因为它是一个异常)

      throw new HttpException(403, "Forbidden");
      

      或者查看Returning HTTP 403 in a WebAPI method,它会创建一个ErrorResponse。

      您可能还需要考虑将其移动到 AuthorizationFilterAttribute 中,因为您正在检查用户的 API 密钥以授权他们执行操作。

      【讨论】:

      • 在这种情况下似乎抛出异常是不对的。
      • 使用异常处理控制流是一种反模式,所以不建议这样做!
      【解决方案5】:

      或者你可以返回:

      filterContext.Result = new ForbidResult();
      

      【讨论】:

      • 这是最好的评论,而不是答案。
      • 如果未设置某些身份验证方案,则会尝试执行重定向并返回错误请求 (400)。
      【解决方案6】:

      你可以抛出 HttpException :

       throw new HttpException(403, "Forbidden");
      

      更多详情,请访问 ; http://msdn.microsoft.com/fr-fr/library/system.web.httpexception(v=vs.110).aspx

      【讨论】:

      • 使用异常处理控制流是一种反模式,所以不建议这样做!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 2023-03-13
      • 2015-03-03
      • 1970-01-01
      相关资源
      最近更新 更多