How to implement IP whitelists in ASP.NET Core 6

0

When working with applications in ASP.NET Core 6, you’ll often want to whitelist IP addresses to allow client requests only from certain IP addresses, while blocking requests from all other addresses. We do this to protect our API endpoints from potentially malicious requests from malicious actors, while allowing requests from trusted IP addresses.

Also known as an IP safelist, an IP whitelist helps ensure that our application’s sensitive data is only exposed to IP addresses that we know and trust. An IP address whitelist can be implemented in ASP.NET Core using middleware or using MVC action filters. This article shows how we can implement IP whitelisting in ASP.NET Core 6 using middleware.

To work with the code samples provided in this article, you must have Visual Studio 2022 installed on 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, let’s create an ASP.NET Core project in Visual Studio 2022. Follow these steps to create a new ASP.NET Core Web API project in Visual Studio 2022:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create a new project”.
  3. In the “Create a 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 of the new project.
  6. Optionally check the box “Place the solution and the project in the same directory”, according to your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown below, ensure that the “Use Controllers…” box is checked. Leave the “Authentication type” set to “None” (default). And make sure the “Enable Docker”, “Configure for HTTPS”, and “Enable Open API Support” checkboxes are unchecked as we won’t be using any of these features here.
  9. Click Create.

We’ll be using this ASP.NET Core 6 Web API project to work with IP whitelists in later sections of this article.

The Program class in ASP.NET Core 6

Program and Startup are the main configuration classes for your .NET applications. However, ASP.NET Core 6 provides a simplified programming and hosting model that removes most of the boilerplate code. You don’t have the Startup class now. Instead, you should write your code to set up the request processing pipeline in the Program class.

When you create a new ASP.NET Core 6 project in Visual Studio, the Program class looks like this:

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseAuthorization();
app.MapControllers();
app.Run();

We will use this Program class in the following sections of this article. But first let’s look at how we can implement an IP whitelist middleware in ASP.NET Core 6.

Specify whitelist IP addresses in the configuration file

Specify the following whitelisted IP addresses in the appsettings.json file.

"IPWhitelistOptions": {
    "Whitelist": [ "192.168.0.9", "192.168.1.9", "::1" ]
  }

Note that these IP addresses are provided for informational purposes only. You must replace these IP addresses with the IP addresses you want to whitelist.

Now create a new class named IPWhitelistOptions with the following code, which will read the configuration values ​​(IP addresses) we just specified.

public class IPWhitelistOptions
{
   public List Whitelist { get; set; }
}

Create the IPWhitelistMiddleware class

To create our middleware that will whitelist our IP addresses, create a new class called IPWhitelistMiddleware with the following code.

public class IPWhitelistMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IPWhitelistOptions _iPWhitelistOptions;
        private readonly ILogger _logger;
        public IPWhitelistMiddleware(RequestDelegate next,
        ILogger logger,
            IOptions applicationOptionsAccessor)
        {
            _iPWhitelistOptions = applicationOptionsAccessor.Value;
            _next = next;
            _logger = logger;
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Method != HttpMethod.Get.Method)
            {
                var ipAddress = context.Connection.RemoteIpAddress;
                List whiteListIPList =
                _iPWhitelistOptions.Whitelist;
                var isIPWhitelisted = whiteListIPList
                .Where(ip => IPAddress.Parse(ip)
                .Equals(ipAddress))
                .Any();
                if (!isIPWhitelisted)
                {
                    _logger.LogWarning(
                    "Request from Remote IP address: {RemoteIp}
                    is forbidden.", ipAddress);
                    context.Response.StatusCode =
                    (int)HttpStatusCode.Forbidden;
                    return;
                }
            }            
            await _next.Invoke(context);
        }
    }

Note that in this example, whitelisting IP addresses will work for all HTTP verbs except HTTP Get. If you want this whitelist to apply to all HTTP verbs, you can simply comment out the following statement in the Invoke method.

if (context.Request.Method != HttpMethod.Get.Method)

In the Invoke method of our middleware, we read all the whitelisted IP addresses into a list of strings. If the IP address originating the request matches one of the IP addresses in the list, the request is allowed; otherwise, the middleware returns HTTP 403 Forbidden and a log message is generated accordingly.

The IPWhitelistMiddlewareExtensions class

Now create a class named IPWhitelistMiddlewareExtensions and enter the following code.

 public static class IPWhitelistMiddlewareExtensions
    {
        public static IApplicationBuilder UseIPWhitelist(this
        IApplicationBuilder builder)
        {
            return builder.UseMiddleware();
        }
    }

We will use our IP whitelist middleware in the Program class as shown in the next section.

Configure IP whitelist middleware in Program class

You need to configure the IP whitelist middleware in the Program class using the Configure method of the Service collection as shown in the code snippet below.

builder.Services.Configure(builder.Configuration.GetSection("IPWhitelistOptions"));

Now insert the following line of code into the Program class to take advantage of the extension method we created earlier.

app.UseIPWhitelist();

This is what your Program class should look like now:

using IPWhiteListDemo;
using System.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure(builder.Configuration.GetSection("IPWhitelistOptions"));
builder.Services.AddControllers();
var app = builder.Build();
app.UseIPWhitelist();
app.UseAuthorization();
app.MapControllers();
app.Run();

Finally, run the application by pressing the F5 key in Visual Studio. To test the middleware, you can issue an HTTP Post request from Postman. If your IP address matches one of the whitelisted IP addresses, the request will be allowed. Otherwise, the request will be denied and the middleware will return HTTP 403 Forbidden.

Copyright © 2022 IDG Communications, Inc.

Share.

Comments are closed.