401 HTTP Status Code in ASP.NET Core Web API

401 HTTP Status Code in ASP.NET Core Web API

In this article, I will discuss How to Return 401 Unauthorized HTTP Status Code from the ASP.NET Core Web API Controller Action method with Examples. Please read our previous article discussing How to Return 400 HTTP Status Code in ASP.NET Core Web API with Examples.

401 HTTP Status Code

The 401 HTTP Status Code indicates an “Unauthorized” response. This status code is sent by a web server when access to the requested resource requires authentication, and either the authentication has not been provided or has failed. It suggests that the client needs to authenticate themselves in order to get the requested response. The following are the key points about the 401 HTTP Status Code:

  • Authentication Required: The primary purpose of this status code is to inform the client that they must authenticate themselves to get the requested response.
  • WWW-Authenticate Header: When a server sends a 401 response, it also includes a WWW-Authenticate header field, indicating the authentication method that should be used to gain access. This header provides the information required for the client to initiate the authentication process.
  • Client Action: Upon receiving a 401 response, the client may submit a new request with the appropriate authentication credentials. This is usually done by including an Authorization header in the request with the credentials.
  • Difference from 403 Forbidden: A 401 status code is different from a 403 Forbidden status code, which indicates that the server understands the client’s request but refuses to authorize it. In contrast, 401 suggests that the request could be authorized if credentials were provided.
401 HTTP Status Code in ASP.NET Core Web API

The 401 HTTP status code is used to indicate that a request has not been executed because it lacks valid authentication credentials for the targeted resource. When you are working with ASP.NET Core Web API and encounter a 401 Status Code, it typically means one of the following:

  • No Authentication Information: The request did not contain any authentication information. This is common when the API endpoint expects a token (like JWT), and the request is made without it.
  • Invalid Authentication Information: The request contains authentication information, but it is invalid or expired. This can happen if the token is not valid, is expired, or does not have the correct permissions to access the resource.
  • Authentication Scheme Not Supported: The authentication information is provided using a scheme that is not supported or not correctly implemented in the API.

Note: In our upcoming article, we will discuss how to implement authentication and secure our endpoint. In this article, I am just going to give you an overview of the 401 Status Code by returning the same from our action method.

How to Return 401 HTTP Status Code in ASP.NET Core Web API?

To return a 401 Unauthorized HTTP Status Code in an ASP.NET Core Web API, you can use the Unauthorized method from the controller. This method is part of the ControllerBase class, which your controller likely inherits from if it’s an API controller. Returning a 401 Status Code is typically used when an incoming request lacks valid authentication credentials for the requested resource. Here is a basic example of how to do this within an action method of your controller:

using Microsoft.AspNetCore.Mvc;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [HttpGet]
        public IActionResult SecureResource()
        {
            // Your authentication logic here
            // Assuming this is the result of your auth check
            bool isAuthenticated = false; 

            if (!isAuthenticated)
            {
                return Unauthorized(); // Returns a 401 Unauthorized response
            }

            // Proceed with normal action if authenticated
            return Ok("Authenticated and Authorized Access.");
        }
    }
}

In the above example, the SecureResource method checks if a user is authenticated using a hypothetical condition. If isAuthenticated is false, it returns a 401 Unauthorized status code by calling the Unauthorized() method without any parameters. Now, if you access the endpoint using Postman, then you will get the following response:

If you need to include additional information with the 401 Response, such as details about why the request is unauthorized or how to authenticate, you can pass an object to the Unauthorized method. For a better understanding, please modify the Controller as follows:

using Microsoft.AspNetCore.Mvc;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [HttpGet]
        public IActionResult SecureResource()
        {
            // Your authentication logic here
            // Assuming this is the result of your auth check
            bool isAuthenticated = false; 

            if (!isAuthenticated)
            {
               // Returns a 401 Unauthorized response
                return Unauthorized(new { message = "Access denied. Please provide valid credentials." });
            }

            // Proceed with normal action if authenticated
            return Ok("Authenticated and Authorized Access.");
        }
    }
}

This would still return a 401 Status Code, but the response body will include the JSON object with the message property, as shown in the image below.

Manually Returning 401 Error Response:

Using the StatusCode method, we can also return the 401 Unauthorized Response along with the custom data. For a better understanding, please modify the controller as follows:

using Microsoft.AspNetCore.Mvc;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [HttpGet]
        public IActionResult SecureResource()
        {
            // Your authentication logic here
            // Assuming this is the result of your auth check
            bool isAuthenticated = false;

            if (!isAuthenticated)
            {
                // Returns a 401 Unauthorized response
                var errorResponse = new
                {
                    StatusCode = StatusCodes.Status401Unauthorized,
                    Message = "Access denied. Please provide valid credentials."
                };

                // Use StatusCode method to return 401 Unauthorized status and custom data
                return StatusCode(StatusCodes.Status401Unauthorized, errorResponse);
            }

            // Proceed with normal action if authenticated
            return Ok("Authenticated and Authorized Access.");
        }
    }
} 
Response:

Manually Returning 401 Error Response

Custom Middleware to Handle 401 Unauthorized Error

For scenarios that require custom logic or handling across multiple endpoints, you can implement a middleware that inspects requests and decides whether to proceed or return a 401 response. So, create a class file named CustomAuthenticationMiddleware.cs and copy and paste the following code.

namespace ReturnTypeAndStatusCodes.Models
{
    public class CustomAuthenticationMiddleware
    {
        private readonly RequestDelegate _next;

        public CustomAuthenticationMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // Custom authorization logic here
            bool isAuthorized = CheckAuthorization(context);

            if (!isAuthorized)
            {
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                context.Response.ContentType = "application/json";

                var customResponse = new
                {
                    status = 401,
                    message = "Unauthorized. Please Provide Valid Credentials"
                };

                await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(customResponse));
                return; // Short-circuit the pipeline
            }

            await _next(context);
        }

        private bool CheckAuthorization(HttpContext context)
        {
            // Implement your authorization logic here
            // For example, check for a specific header or token
            return false; // Simulate unauthorized
        }
    }
}
In the above example:
  • RequestDelegate _next: A delegate that represents the next middleware component in the request processing pipeline. It’s stored in a private read-only field and initialized through the constructor.
  • Constructor: The constructor takes a RequestDelegate parameter representing the next piece of middleware in the pipeline. This delegate is assigned to the _next field.
  • InvokeAsync Method: This is the method called when the middleware executes. It receives the HttpContext as a parameter, which provides information about the incoming HTTP request.
  • CheckUserAuthorization: This method is used to determine if the request is authorized. This would contain your custom authorization logic. Here, we are simply returning false to handle the unauthorized scenario.
  • If isAuthorized is false, it sets the response’s status code to 401 Unauthorized and specifies the content type as JSON.
  • Custom Response: A custom response object is created and serialized into JSON. This JSON string is then written to the response body. This step customizes the error message sent to the client, providing more detail about why the request was Unauthorized.
  • return: The return statement ensures that the middleware pipeline execution stops here for unauthorized requests, preventing further processing by subsequent middleware components or the request from reaching the resource it was intended for.
  • _next(context): If the request is authorized, the middleware passes control to the next component in the pipeline by calling _next with the context.
Registration the Middleware

Once you define the custom middleware, then you need to register it within your application’s request processing pipeline, typically in the Program.cs file, using the UseMiddleware extension method. This ensures that your middleware is executed for every incoming HTTP request. So, please add the following statement to the Program.cs class file:

app.UseMiddleware<CustomAuthenticationMiddleware>();

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 SecureResource()
        {
            // Proceed with normal action if authenticated
            return Ok("Authenticated and Authorized Access.");
        }
    }
}

Now, run the application and access the above endpoint, and you should get the following 401 Unauthorized response:

Notes
  • Ensure that the middleware is registered at the appropriate point in the pipeline. It should be registered before any middleware that needs to know the authorization status.
  • Modify the CheckAuthorization method to implement your specific authorization logic.
  • This approach allows you to return custom data in the response body for unauthorized requests, making your API responses more informative and useful for client applications.
When Should We Use 401 HTTP Status Code in ASP.NET Core Web API?

The 401 HTTP Status Code should be used in ASP.NET Core Web API (or any web API) when an incoming request lacks valid authentication credentials for the requested resource or if the authentication credentials provided are not sufficient to access the resource. It signifies that the request has not been applied because it lacks valid authentication credentials for the target resource. Here are key scenarios when you should use the 401 Status Code in your ASP.NET Core Web API:

  • Unauthorized Access Attempt: When a request is made to a protected resource without providing authentication credentials, or if the credentials are missing, the server should respond with a 401 Unauthorized status code.
  • Invalid or Expired Authentication Token: If the request contains an authentication token (such as a JWT token) and the token is invalid, expired, or does not grant access to the requested resource, the server should respond with a 401 Status Code.
  • Authentication Required: The 401 Status Code is appropriate to indicate that the client must authenticate itself to get the requested response. This is a signal to the client that it should prompt the user to provide authentication credentials.

In the next article, I will discuss How to Return 403 HTTP Status Code in ASP.NET Core Web API with Examples. In this article, I try to explain How to Return 401 Unauthorized HTTP Status Code in ASP.NET Core Web API with Examples, and I hope you enjoy this article on “401 Unauthorized HTTP Status Code in the ASP.NET Core Web API”.

Leave a Reply

Your email address will not be published. Required fields are marked *