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!