How to return 403 Forbidden response as IActionResult in ASP.NET Core
C#asp.net CoreC# Problem Overview
I would like to return a 403 Forbidden to the client when trying to perform an invalid operation. What is the method I need to use?
I searched over the internet but I found only these for MVC 5:
> If the return type for your web api method is HttpResponseMessage then
> you need to use the below code:
>
> 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.");
>
> How to return 403 for IActionResult type:
>
> public IActionResult Put(string userid, [FromBody]Setting setting)
> {
> var result = _SettingsRepository.Update(userid, setting);
> if (result == true)
> {
> return Ok(201);
> }
> else
> {
> return BadRequest();
> }
> }
C# Solutions
Solution 1 - C#
When you want to respond with a HTTP 403 status and allow ASP.NET Core's authentication logic to handle the response with its forbidden handling logic (can be configured in your Startup
class, and may cause a redirect to another page), use:
return Forbid();
(same applies to Unauthorized()
)
When you want to respond with a HTTP 403 status code from an API and do not want the ASP.NET Core authentication logic to perform any redirect or other action, use:
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
);
The latter example produces a client error response.
Solution 2 - C#
Alternative to MstfAsan's answer is to use:
return Forbid();
It is a method on the controller base class that does the same thing.
Or
return StatusCode(403);
If you want to return a message, then you must use StatusCode
.
Solution 3 - C#
You can use return new ForbidResult();
Class declaration is
public class ForbidResult : ActionResult, IActionResult
For more spesific usages visit https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.mvc.forbidresult
Solution 4 - C#
Simply you can use ObjectResult to return a custom response with a status code.
See the syntax,
return new ObjectResult("Message") {StatusCode = YOUR_STATUS_CODE };
Note - You can pass an object also,
return new ObjectResult(your_model) {StatusCode = YOUR_STATUS_CODE };
Example:
public async Task<IActionResult> Post([FromBody] SomeData _data)
{
// do your stuff
// return forbidden with custom message
return new ObjectResult("Forbidden") { StatusCode = 403};
}
Solution 5 - C#
If you don't return IActionResult
as result, you can use the following code :
public List<SomeModel> GetModels()
{
...
... // check logic
...
Response.StatusCode = 403;
return new List<SomeModel>();
}
Solution 6 - C#
Having the same issue when migrate from asp net mvc to net core 5. As a decision you can inherit from 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);
}
}
and return it as IActionResult:
[HttpGet]
public IActionResult Get(int bookId)
{
var book = dbContext.BookRepository.Find(bookId);
if (!CurrentUser.CanEditAsClient(book))
{
return new ForbidActionResult();
}
return Ok();
}