Back to: ASP.NET Core Web API Tutorials
403 HTTP Status Code in ASP.NET Core Web API
In this article, I will discuss How to Return a 403 Forbidden HTTP Status Code from the ASP.NET Core Web API Controller Action method with Examples. Please read our previous article on discussing How to Return 401 HTTP Status Code in ASP.NET Core Web API with Examples.
What is 403 HTTP Status Code?
The HTTP 403 status code indicates “Forbidden.” This means that the server understood the request but refused to authorize it. This typically means that the client does not have the necessary permissions to access the requested resource, even though it has provided valid authentication credentials. That means the server is saying, “I understand your request, but I won’t fulfill it because you don’t have permission to access this content.” This can occur for several reasons, including:
- Insufficient Permissions: The user or client does not have the required permissions to access the resource. This might be due to role-based access control settings or specific security policies.
- IP Blocking: The server may be configured to deny access to specific IP addresses or ranges. If the client’s IP falls within this range, it will receive a 403 response.
- Resource Restrictions: The server might restrict the requested resource, such as a file or directory that is not accessible to certain users.
- CSRF Protection: Some servers implement Cross-Site Request Forgery (CSRF) protection, which can result in a 403 status code if the request fails to include the necessary CSRF token.
How to Resolve 403 Error?
When encountering a 403 Forbidden error, users can attempt several steps to resolve the issue, including:
- Check Permissions: Ensure the user or client has the correct permissions to access the resource.
- Verify Credentials: Ensure the credentials provided are correct and have the necessary access rights.
- Review Server Configuration: Check the server’s configuration for any restrictions or policies that might be causing the issue.
- Examine IP Restrictions: Verify if there are any IP-based restrictions that could be blocking access.
- Clearing Cache: Clearing the browser’s cache and cookies as outdated or corrupt stored data can sometimes cause this error.
Note: Contact the website or server administrator for information on why access is denied or to request access if it’s a resource you should legitimately be able to access.
How to Return 403 HTTP Status Code in ASP.NET Core Web API?
In ASP.NET Core Web API, we can return a 403 Forbidden HTTP status code in several ways, depending on the context of our application and the flow of our logic.
Using the StatusCode method to Return 403 HTTP Status Code without Data
To return a 403 HTTP status code in an ASP.NET Core Web API, we can use the StatusCode method available in the ControllerBase class. This method provides a convenient way to return an HTTP status code along with an optional payload. For a better understanding, please modify the Employee Controller as follows. Here, we return a 403 Forbidden response without data using the StatusCode method:
using Microsoft.AspNetCore.Mvc; namespace ReturnTypeAndStatusCodes.Controllers { [Route("api/[controller]")] [ApiController] public class EmployeeController : ControllerBase { [HttpGet] public IActionResult GetResource() { // Your logic here // For example, check if the user has the right permissions to access the resource bool hasPermission = CheckUserPermission(); if (!hasPermission) { // User does not have the required permissions // Return a 403 Forbidden response return StatusCode(StatusCodes.Status403Forbidden); } // If the user has permission, continue to handle the request // For example, return the requested resource return Ok("Resource Content Here"); } private bool CheckUserPermission() { //Logic to Check the User Permission return false; } } }
In this example, CheckUserPermission() represents a hypothetical method that checks if the current user has the necessary permissions to access a particular resource. If the user does not have the permissions, the method returns a 403 Forbidden status code by calling StatusCode(StatusCodes.Status403Forbidden). Otherwise, it proceeds with handling the request (e.g., returning the requested resource).
Response:
Using the StatusCode method to Return 403 HTTP Status Code with Data
Now, let us see how to return the 403 HTTP Status Code with Data. Please modify the Employee Controller as follows. Here, we are using the overloaded version of the StatusCode method, which takes two parameters: the integer status code and object values.
using Microsoft.AspNetCore.Mvc; namespace ReturnTypeAndStatusCodes.Controllers { [Route("api/[controller]")] [ApiController] public class EmployeeController : ControllerBase { [HttpGet] public IActionResult GetResource() { // Your logic here // For example, check if the user has the right permissions to access the resource bool hasPermission = CheckUserPermission(); if (!hasPermission) { // User does not have the required permissions // Return a 403 Forbidden response var errorResponse = new { StatusCode = StatusCodes.Status403Forbidden, Message = "Access denied. You do not have permission to access this resource." }; // Use StatusCode method to return 403 Forbidden status and custom data return StatusCode(StatusCodes.Status403Forbidden, errorResponse); } // If the user has permission, continue to handle the request // For example, return the requested resource return Ok("Resource Content Here"); } private bool CheckUserPermission() { //Logic to Check the User Permission return false; } } }
Response:
Custom Middleware to Handle 403 Forbidden Error
For more global or complex scenarios, such as IP blocking, you might implement a middleware that checks conditions and returns a 403 status code. Let us understand this with one example. Please create a class file named CustomAuthorizationMiddleware.cs and copy and paste the following code. The following code is self-explained; please read the comment lines for a better understanding.
// Importing the JSON serialization library using System.Text.Json; namespace ReturnTypeAndStatusCodes.Models { // Custom middleware class for handling authorization public class CustomAuthorizationMiddleware { // Field to hold the next middleware component in the pipeline private readonly RequestDelegate _next; // Constructor to initialize the middleware with the next delegate public CustomAuthorizationMiddleware(RequestDelegate next) { _next = next; // Assign the next delegate to the field } // The main method called by the ASP.NET Core pipeline public async Task Invoke(HttpContext context) { // Custom logic to determine if the user is authorized bool isAuthorized = CheckUserAuthorization(context); // If the user is not authorized if (!isAuthorized) { // Set the HTTP status code to 403 Forbidden context.Response.StatusCode = StatusCodes.Status403Forbidden; // Set the response content type to JSON context.Response.ContentType = "application/json"; // Create a custom response object var customResponse = new { Code = 403, // Custom code for forbidden status Message = "Access is denied due to insufficient permissions." // Custom message }; // Serialize the custom response object to JSON var responseJson = JsonSerializer.Serialize(customResponse); // Write the JSON response to the HTTP response body await context.Response.WriteAsync(responseJson); return; // Short-circuit the middleware pipeline } // If the user is authorized, call the next middleware in the pipeline await _next(context); } // Custom method to check user authorization private bool CheckUserAuthorization(HttpContext context) { // Implement your authorization logic here // For this example, returning false to simulate a forbidden scenario return false; } } }
Registration the Middleware
After defining the middleware, then we need to register it within your application request processing pipeline, typically in the Program.cs file, using the UseMiddleware extension method. This ensures that the custom middleware is executed for every incoming HTTP request. So, please add the following statement to the Program.cs class file before the MVC Middleware Component:
app.UseMiddleware<CustomAuthorizationMiddleware>();
Modifying the Employee Controller:
Next, modify the Employee Controller as follows:
using Microsoft.AspNetCore.Mvc; namespace ReturnTypeAndStatusCodes.Controllers { [Route("api/[controller]")] [ApiController] public class EmployeeController : ControllerBase { [HttpGet] public IActionResult GetResource() { return Ok("Resource Content Here"); } } }
Now, run the application and access the above endpoint, and you should get the following 403 Forbidden response:
When Should We Return 403 HTTP Status Code in ASP.NET Core Web API?
In ASP.NET Core Web API, returning a 403 Forbidden HTTP status code is appropriate under specific circumstances related to security and authorization. The following are some of the key scenarios where returning a 403 status code is considered appropriate:
- Insufficient Permissions: If a user is authenticated but does not have the necessary permissions to access a particular resource or perform an action, you should return a 403 status code. For example, a regular user trying to access an admin-only endpoint, a user without the required roles, or claims trying to access a resource restricted to certain roles.
- Role-Based Access Control: When using role-based access control, a user might be authenticated but still lack the required role to access a specific resource. For example, restricting access based on custom rules or conditions that go beyond simple role-based checks.
- Forbidden IP Addresses: If the server is configured to deny access from specific IP addresses or ranges, and a request originates from a forbidden IP, a 403 status code should be returned.
- Directory Listings Denied: When a client tries to access a directory on the server where directory listing is not allowed, the server should return a 403 status code.
- Cross-Site Request Forgery (CSRF): If a request is missing the required CSRF token, the server should return a 403 status code to indicate that the request is not authorized.
Comparison with 401 Unauthorized:
- 401 Unauthorized: Indicates that authentication is required, and the client has not yet provided credentials, or the credentials are invalid.
- 403 Forbidden: This indicates that the server understood the request, the client is authenticated, and the client does not have the necessary permissions to access the resource.
In the next article, I will discuss how to Return a 404 HTTP Status Code in ASP.NET Core Web API with Examples. In this article, I try to explain how to Return a 403 Forbidden HTTP Status Code in ASP.NET Core Web API with Examples. I hope you enjoy this article on “403 Forbidden HTTP Status Code in the ASP.NET Core Web API.”
Nice explanation