How to improve API security in ASP.NET Core

Take advantage of authentication and authorization, API keys, rate limiting, CORS, API versioning, and other recommended practices to build secure and robust APIs in ASP.NET Core.

facade of heavy duty bank vault
Thinkstock

Because our APIs handle private and sensitive data, it is imperative that we adopt proven strategies to secure them. We have many ways to secure APIs, starting with firewalling them behind an API gateway and accessing them over secure connections.

In this article we’ll discuss several ways developers can improve API security, such as by using authentication and authorization, rate limiting, API versioning, and logging and monitoring, and how to implement these in ASP.NET Core 7 applications.

To use the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core 7 Web API project in Visual Studio 2022. Follow the steps outlined below.

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, leave the “Use controllers (uncheck to use minimal APIs)” box checked. We won’t be using minimal APIs in this project.
  9. Elsewhere in the "Additional Information” window, leave the “Authentication Type” set to “None” (the default) and make sure the check boxes “Enable Open API Support,” “Configure for HTTPS,” and “Enable Docker” remain unchecked. We won’t be using any of those features here.
  10. Click Create.

We’ll use this ASP.NET Core Web API project to work with the code examples in the sections below.

What is API security? Why is it important?

An application programming interface (API) is the mechanism through which one software component interacts or exchanges data with other components. APIs are used to connect mobile and web clients with the back end of many applications, and to transmit data between servers and clients over public networks. Consequently, APIs often become a target for hackers. 

API security encompasses the policies, guidelines, and procedures we can adopt to protect APIs against security vulnerabilities and malicious attacks. With the surge in the number of connected devices and the increased adoption of microservices and serverless architectures, the number of APIs in modern-day applications has exploded.

Today's businesses use APIs to connect services and transfer data. If your APIs are compromised, then the sensitive data in your application are compromised as well. In addition to protecting your application’s sensitive data from breaches, you can take advantage of API security to thwart SQL injection, cross-site scripting (XSS), and other attacks.

In the following sections we’ll examine the key strategies we can follow to secure the APIs in our ASP.NET Core applications.

Use authentication and authorization

To secure your APIs, you can take advantage of authentication and authorization. While authentication is used to validate the identity of a user, authorization is used to grant or revoke access to specific resources in the application based on the user’s access privileges. The following code snippet illustrates how you can authorize a user in your ASP.NET Core 7 application.

[ApiController]
[Route("api/[controller]")]
public class DemoController : ControllerBase
{
    [Authorize]
    [HttpGet]
    public IActionResult Get()
    {
        //Write your usual code here
        return Ok("Can be accessed only by authenticated users.");
    }
}

Use token-based authentication

Another technique used to authenticate users in an application is token-based authentication. Here a unique token is generated for each authenticated user, i.e., the token is generated once the identity of the user has been validated. Typically, we use JWT tokens for token-based authentication. For all subsequent requests to the API, the token is passed with the request, preferably in the request header.

Use API keys

You can also use API keys to authenticate users in an application. API keys are unique identifiers that are passed in the request header on each call to the API. The following code snippet shows how you can validate an API key in an ASP.NET Core 7 application.

[ApiController]
[Route("api/[controller]")]
public class DemoController : ControllerBase
{
    private const string API_KEY = "ABCDE12345"; //This is your API key
    [HttpGet]
    public IActionResult Get()
    {
        var apiKey = Request.Headers["Api_Key"].FirstOrDefault();
        if (apiKey != API_KEY)
            return Unauthorized();
        //Write your usual code here
        return Ok("The API key is valid.. Authenticated successful.");
    }
}

Use rate limiting

You can take advantage of rate limiting to protect your API from brute-force attacks. Rate limiting is a technique that allows you to limit the number of calls to an API endpoint within a given time frame. You can use the ASP.NET Core rate limiting middleware to implement rate limiting in your ASP.NET Core 7 applications.

Use cross-origin resource sharing (CORS)

You can use CORS to thwart unauthorized access to your APIs from other domains. The following code snippet illustrates how you can enable CORS at the action level in an ASP.NET Core 7 application.

public class BookController : ApiController
{
   [EnableCors(origins: "http://localhost:8095/",
    headers: "*", methods: "*")]
   public IEnumerable<string> Get()
   {
        return new string[] { "Mastering C# 8.0", "Joydip Kanjilal" };
   }
}

Use API versioning

You can also improve security by versioning your APIs. Versioning allows you to make changes to your API, and deprecate less-secure versions of the API, without breaking the existing clients. ASP.NET Core provides support for API versioning out-of-the-box. To use API versioning, all you need to do is install the ASP.NET API versioning package from NuGet. The following code snippet illustrates how you can use the MapToApiVersion attribute in an action method.

[HttpGet]
[MapToApiVersion("3.0")]
public string Get()
{
   return books;
}

Use logging and monitoring

Logging is integral to providing deeper insights into your application’s behavior. Monitoring is also of paramount importance in detecting and identifying application failures. By using comprehensive logging and monitoring, you will be able to gain a clear picture of API usage and uncover potential security breaches and performance issues associated with your API.

You can choose from a number of frameworks to implement logging in your ASP.NET Core application including Microsoft.Extensions.Logging, NLog, Apache log4net, and Serilog. The following code snippet illustrates how you can take advantage of the built-in default logger in ASP.NET Core to log data in your action methods.

public class DemoController: Controller
{
  private readonly ILogger _logger;
  public DemoController(ILogger <DemoController> logger)
  {
    _logger = logger;
  }
  public IActionResult Index()
  {
    _logger.LogInformation("Inside the Index action method");
    return View();
  }
  public IActionResult Test()
  {
    _logger.LogInformation("Inside the Test action method");
    return View();
  }
}

Other recommendations

API security is constantly evolving. Hence, it is crucial to consider API security at every stage of the development process and to keep up with the current threats and best practices. You should also have a test strategy in place and test your APIs to identify security vulnerabilities.

You should only store the data that you need and only for as long as you need it. Regularly clean up old or unnecessary data. You should update and patch the dependencies of your application regularly. In addition, you can take advantage of two-factor authentication, secure stored passwords using hashing, and implement the principle of least knowledge to provide only necessary access.

Copyright © 2023 IDG Communications, Inc.

How to choose a low-code development platform