After moving my website to dotnet core, in order to make the admin panel more secure, I decided to filter the admin panel and restrict it to my static IPs. there are lots of ways to do that, I personally decided to handle it via middleware. Look a the following piece of code:
public class IPFilterMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<IPFilterMiddleware> _logger;
private readonly string _adminSafeList;
public IPFilterMiddleware(RequestDelegate next, ILogger<IPFilterMiddleware> logger, string adminWhiteList)
{
_adminSafeList = adminWhiteList;
_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 badIp = true;
foreach (var address in ip)
{
var testIp = IPAddress.Parse(address);
if (testIp.GetAddressBytes().SequenceEqual(bytes))
{
badIp = false;
break;
}
}
if (badIp)
{
_logger.LogInformation($"Forbidden Request: {remoteIp}");
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return;
}
}
await _next.Invoke(context);
}
}
The middleware invokes the request and after looking at a string that contains the IPs, it returns a boolean value (badIp). Just like the ordinary way of registering the middleware, we should use it in the Configure() of startup class:
app.UseMiddleware<IPFilterMiddleware>(Configuration["ValidIp"]);
Obviously, we should have the ValidIp in the appsettings.json file:
"ValidIp": "127.0.0.1,192.168.1.5, 97.144.85.243"
And then should create a filter attribute like this:
public class IpCheckFilter : ActionFilterAttribute
{
private readonly ILogger _logger;
public IpCheckFilter(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger("AFilter");
}
public override void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation($"Remote IpAddress: {context.HttpContext.Connection.RemoteIpAddress}");
base.OnActionExecuting(context);
}
}
And then register it as the scope in ConfigureService() of startup:
services.AddScoped<IpCheckFilter>();
That’s all. Now we can use the filter attribute in every controller of the target area:
[Authorize]
[Area("Admin")]
[ServiceFilter(typeof(IpCheckFilter))]
public class ContentController : Controller
{
public IActionResult Index()
{
return View();
}
}
Cheers!