| Muhammad Waseem

About Newsletter
Books
30 .NET Tips
Sponsorship
Client IP safelist for ASP.NET Core
Oct 14, 2023
3 min read

Client IP safelist for ASP.NET Core

Sponsor this Newsletter

What is client IP safe list technique

In this technique we track every request coming to our API and check its IP address, then we check list of our safe IP lists, if it exists in that list we allow it otherwise we don’t allow it to move on relevant controller.

Benefits of white listing IPs

This technique comes under security concerns, following are the benefits :

  • Enhanced security
  • Reduced attack surface
  • Prevention of unauthorized access

At which level of application we should restrict it

We can apply this restriction at three levels:

1/ Cloud level ( e.g. using azure services )

2/ Network level ( e.g. firewall )

3/ Application level ( that we are going to do )

The more higher you can go would be more appropriate unless you have some IF/ELSE that forces you to come at low level.

Fun fact : We can apply whitelisting technique via load balancer or rate limiter as well.

Enough talking let’s dive into code implementation.

Ways to whitelist IP it in .NET API

We have two ways to achieve it:

1/ Via Middleware ( I already wrote about middlewares )

2/ Via Action Filters ( Read a previous newsletter of mine on action filters )

Before moving on let’s add list of allowed IPs in appsetting


{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "SafeIPs": "127.0.0.1;192.168.1.5;119.156.228.255",
  "AllowedHosts": "*"
}

1/ Implementing via Middleware: So let’ add the middleware, whose code looks like this

public class WhitelistIpMiddleware : IMiddleware
{
    private readonly string _safelist;
    private readonly ILogger _logger;
    public WhitelistIpMiddleware(string safelist, ILogger logger)
    {
        _safelist = safelist;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var remoteIp = context.Connection.RemoteIpAddress;
        if (remoteIp == null)
        {
            _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp);
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }
        var ipList = _safelist.Split(';');
        var badIp = true;
        if (remoteIp.IsIPv4MappedToIPv6)
        {
            remoteIp = remoteIp.MapToIPv4();
        }
        foreach (var address in ipList)
        {
            var testIp = IPAddress.Parse(address);
            if (testIp.Equals(remoteIp))
            {
                badIp = false;
                break;
            }
        }
        if (badIp)
        {
            _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp);
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }
        await next.Invoke(context);
    }
}

And don’t forget to register the middleware

var safelist = builder.Configuration["SafeIPs"];
builder.Services.AddScoped<WhitelistIpMiddleware>(provider =>
{
    var logger = provider.
    GetRequiredService<ILogger<WhitelistIpMiddleware>>();
    return new WhitelistIpMiddleware(safelist, logger);
});

2/ Via Action Filter: Let’s create an action filter that looks like this :

var safelist = builder.Configuration["SafeIPs"];
builder.Services.AddScoped<WhitelistIpMiddleware>(provider =>
{
    var logger = provider.GetRequiredService<ILogger<WhitelistIpMiddleware>>();
    return new WhitelistIpMiddleware(safelist, logger);
});

Register action filter service:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Net;
public class WhitelistIpActionFilter : ActionFilterAttribute
{
    private readonly string _safelist;
    private readonly ILogger<WhitelistIpActionFilter> _logger;
    public WhitelistIpActionFilter(string safelist, ILogger<WhitelistIpActionFilter> logger)
    {
        _safelist = safelist;
        _logger = logger;
    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
        if (remoteIp == null)
        {
            _logger.LogWarning("Forbidden Request from null IP address");
            context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
            return;
        }
        _logger.LogDebug("Remote IpAddress: {RemoteIp}", remoteIp);
        var ipSafelist = _safelist.Split(';');
        bool isAllowedIp = false;
        if (remoteIp.IsIPv4MappedToIPv6)
        {
            remoteIp = remoteIp.MapToIPv4();
        }
        foreach (var address in ipSafelist)
        {
            if (IPAddress.TryParse(address, out var testIp) && testIp.Equals(remoteIp))
            {
                isAllowedIp = true;
                break;
            }
        }
        if (!isAllowedIp)
        {
            _logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp);
            context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
            return;
        }
        base.OnActionExecuting(context);
    }
}

Now we can apply this filter on any method in controller and even at controller level as well.

var safelist = builder.Configuration["SafeIPs"];
builder.Services.AddScoped(provider =>
{
    var logger = provider.GetRequiredService<ILogger<WhitelistIpActionFilter>>();
    return new WhitelistIpActionFilter(safelist, logger);
});

Find code of this newsletter issue at my GitHub Repo

This article was originally published at https://mwaseemzakir.substack.com/ on Oct 14, 2023 .

Whenever you're ready, there are 3 ways I can help you:

  1. Subscribe to my youtube channel : For in-depth tutorials, coding tips, and industry insights.
  2. Promote yourself to 9,000+ subscribers : By sponsoring this newsletter
  3. Patreon community : Get access to all of my blogs and articles at one place
Previous Next

Subscribe to Newsletter

Join 9,000 Software Engineers

Buy Me a Coffee

Enjoy my articles? Support me by buying a coffee!

Buy Me a Coffee

Muhammad Waseem

Resources
  • Books
  • Courses
Newsletter
  • Articles
  • Sponsorship
Books
  • 30 .NET Tips
  • 100 .NET Tips (Soon)
Author
  • About Us
  • Contact Us
Policy
  • Privacy Policy
  • Terms and Conditions
Interview
  • C# & .NET
  • Web API

Join my .NET newsletter and stay updated!

© 2025 Muhammad Waseem. All rights reserved.