0
votes

I am trying to get client IP and compare values with the configuration. If it matches need to return true/false. How do I make this variable accessible to web application? I am new to .NET core. thanks

I have followed this article to create middleware class but not sure how to pass variable from this context.

https://docs.microsoft.com/en-us/aspnet/core/security/ip-safelist?view=aspnetcore-2.2

    public class SafeListMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<SafeListMiddleware> _logger;
        private readonly string _adminSafeList;

        public SafeListMiddleware(
            RequestDelegate next,
            ILogger<SafeListMiddleware> logger,
                    string adminSafeList)
        {
            _adminSafeList = adminSafeList;
            _next = next;
            _logger = logger;
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Method != "GET")
            {
                var remoteIp = context.Connection.RemoteIpAddress;

                string[] ip = _adminSafeList.Split(';');

                var bytes = remoteIp.GetAddressBytes();
                var match = false;
                foreach (var address in ip)
                {
                    var testIp = IPAddress.Parse(address);
                    var rangeA = IPAddressRange.Parse(address);
                    if(rangeA.Contains(remoteIp))
                    {
                        match = true;
                        break;
                    }
                }
            }

            await _next.Invoke(context);
        }  
    }
}
2

2 Answers

0
votes

I would create an interface such as:

public interface IIPChecker
{
    bool IsSafe(IPAddress remoteIpAddress);
}

with an implementation:

public class IPChecker : IIPChecker
{
    private readonly IPAddress[] _safeList;

    public IPChecker(string safeList)
    {
        var _safeList = safeList
            .Split(';')
            .Select(IPAddress.Parse)
            .ToArray();
    }

    public bool IsSafe(IPAddress remoteIpAddress)
    {
        return _safeList.Contains(remoteIpAddress);
    }
}

and inject it in the controllers that need it:

public class ValuesController : ControllerBase
{
    private readonly IIPChecker _ipChecker;

    public ValuesController(IIPChecker ipChecker)
    {
        _ipChecker = ipChecker;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        var isValid = _ipChecker.IsSafe(HttpContext.Connection.RemoteIpAddress);

        .....
    }
}

If you need this information in all controllers, you can change them to inherit from something like

public class IpCheckController : ControllerBase
{
    private readonly IIPChecker _ipChecker;

    public IpCheckController(IIPChecker ipChecker)
    {
        _ipChecker = ipChecker;
    }

    private bool IsSafe => _ipChecker.IsSafe(HttpContext.Connection.RemoteIpAddress);
}
0
votes

To get the client RemoteIp and compare with the configuration values. you have to first define Http Accessor in the Startup file like below.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

and then in the Middleware access the RemoteIp using below code and compare the value.

var remoteIp = context.Request.HttpContext.Connection.RemoteIpAddress.ToString();