【问题标题】:How to return 403 Forbidden response as IActionResult in ASP.NET Core如何在 ASP.NET Core 中将 403 Forbidden 响应作为 IActionResult 返回
【发布时间】:2017-07-14 06:10:52
【问题描述】:

我想在尝试执行无效操作时向客户端返回 403 Forbidden。我需要使用什么方法?

我在互联网上搜索,但只找到 MVC 5 的这些:

如果您的 web api 方法的返回类型是 HttpResponseMessage 那么 您需要使用以下代码:

return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "RFID is disabled for this site.");
Or  if the return type for your web api method is IHttpActionResult then you need to use the below code

return StatusCode(HttpStatusCode.Forbidden,"RFID is disabled for this site.");

IActionResult 类型如何返回 403:

public IActionResult Put(string userid, [FromBody]Setting setting)
 {
    var result = _SettingsRepository.Update(userid, setting);
    if (result == true)
    {
       return Ok(201);
    }
    else
    {
       return BadRequest();
    }
 }

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    当你想要响应 HTTP 403 状态并且 允许 ASP.NET Core 的身份验证逻辑使用其禁止的处理逻辑来处理响应(可以在你的 Startup 类中配置,并且可以导致重定向到另一个页面),使用:

    return Forbid();
    

    (同样适用于Unauthorized()


    如果您想从 API 响应 HTTP 403 状态代码并且不希望 ASP.NET Core 身份验证逻辑执行任何重定向或其他操作,请使用:

    return StatusCode(403);
    
    // or with developer-friendly type
    return StatusCode(StatusCodes.Status403Forbidden);
    
    // or as an api-friendly error response
    return Problem(
        type: "/docs/errors/forbidden",
        title: "Authenticated user is not authorized.",
        detail: $"User '{user}' must have the Admin role.",
        statusCode: StatusCodes.Status403Forbidden,
        instance: HttpContext.Request.Path
    );
    

    后一个示例生成client error response

    【讨论】:

    • 稍微干净一点的版本是return StatusCode((int)HttpStatusCode.Forbidden, messageOrSerializeableObject);
    • 其实有一个比@MovGP0 建议的更简单的方法return StatusCode(StatusCodes.Status403Forbidden, <you object>);
    • 我正在寻找如何在 Startup.cs 中设置东西,正如 Bart 所提到的,这是一个有趣的线程:stackoverflow.com/questions/35656828/…
    • 顺便说一句,您可以使用Forbid() 并通过覆盖此处描述的身份验证事件来抑制重定向 - stackoverflow.com/a/42030138/968003
    【解决方案2】:

    MstfAsan 的替代方案是使用:

    return Forbid();
    

    它是控制器基类上的一个方法,做同样的事情。

    或者

    return StatusCode(403);
    

    如果要返回消息,则必须使用StatusCode

    【讨论】:

    • 请注意,在 ASP.NET Core 2 中,返回 ForbidResult(由 Forbid 返回)将触发与框架的身份验证代码的某种交互 - 如果您尚未设置以框架理解的方式进行身份验证 - 抛出错误 "No authenticationScheme is specified, and there was no DefaultChallengeScheme found." 如果您不想与 ASP.NET Core 的身份验证集成,请坚持返回 StatusCodeResult 以避免此错误。
    • 在 Api 控制器中使用 Forbid() 将尝试重定向到 Acccout/AccessDenied,即使我更改了 DefaultForbidScheme。只有 StatusCode(403) 似乎工作正常。
    【解决方案3】:

    可以使用return new ForbidResult();类声明

    public class ForbidResult : ActionResult, IActionResult
    

    更多特殊用法请访问https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.forbidresult

    【讨论】:

    • 有趣的是,ForbidResult 并没有从 StatusCodeResult 继承,至少在 ASP NET CORE 2.2 中是这样。
    【解决方案4】:

    您只需使用 ObjectResult 即可返回带有状态码的自定义响应。

    查看语法,

    return new ObjectResult("Message") {StatusCode = YOUR_STATUS_CODE };
    

    注意- 你也可以传递一个对象,

    return new ObjectResult(your_model) {StatusCode = YOUR_STATUS_CODE };
    

    示例:

    public async Task<IActionResult> Post([FromBody] SomeData _data)
    {
         // do your stuff
    
        // return forbidden with custom message
        return new ObjectResult("Forbidden") { StatusCode = 403};
    }
    

    【讨论】:

      【解决方案5】:

      如果您不返回ActionResult 进行响应,您可以使用以下代码:

      public List<SomeModel> get()
      {
         ... 
         ... // check logic
         ...
      
         Response.StatusCode = 403;
         return new List<SomeModel>();
      }
      

      【讨论】:

        【解决方案6】:

        从 asp net mvc 迁移到 net core 5 时遇到同样的问题。作为决定,您可以从 ObjectResult 继承:

        public class ForbidActionResult : ObjectResult
        {
            public ForbidActionResult(int statusCode = (int)HttpStatusCode.Forbidden, string errorMessage = null) : 
                base(errorMessage ?? "User is not allowed to enter this page."))
            {
                StatusCode = statusCode;
            }
        
            public override async Task ExecuteResultAsync(ActionContext context)
            {
                await base.ExecuteResultAsync(context);
            }
        }
        

        并将其作为 IActionResult 返回:

        [HttpGet]
        public IActionResult Get(int bookId)
        {
            var book = dbContext.BookRepository.Find(bookId);
        
            if (!CurrentUser.CanEditAsClient(book))
            {
                return new ForbidActionResult();
            }
        
            return Ok();
        }
        

        【讨论】:

          猜你喜欢
          • 2021-10-29
          • 2022-10-04
          • 2010-09-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-05
          • 1970-01-01
          • 2012-03-18
          相关资源
          最近更新 更多