前言
本篇展示了如何在ASP.NET Core应用程序中设置IP白名单验证的2种方式。
你可以使用以下2种方式:
- 用于检查每个请求的远程 IP 地址的中间件。
- MVC 操作筛选器,用于检查针对特定控制器或操作方法的请求的远程 IP 地址。
中间件
Startup.Configure方法将自定义 AdminSafeListMiddleware 中间件类型添加到应用的请求管道。 使用 .NET Core 配置提供程序检索到该安全,并将其作为构造函数参数进行传递。
app.UseMiddleware<AdminSafeListMiddleware>("127.0.0.1;192.168.1.5;::1");
- 1.
中间件将字符串分析为数组,并在数组中搜索远程 IP 地址。 如果找不到远程 IP 地址,中间件将返回 HTTP 403 禁止访问。 对于 HTTP GET 请求,将跳过此验证过程。
public class AdminSafeListMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<AdminSafeListMiddleware> _logger;
private readonly string _safelist;
public AdminSafeListMiddleware(
RequestDelegate next,
ILogger<AdminSafeListMiddleware> logger,
string safelist)
{
_safelist = safelist;
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Method != HttpMethod.Get.Method)
{
var remoteIp = context.Connection.RemoteIpAddress;
_logger.LogDebug("Request from Remote IP address: {RemoteIp}", remoteIp);
string[] ip = _safelist.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.LogWarning(
"Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;
}
}
await _next.Invoke(context);
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
操作筛选器
如果需要针对特定 MVC 控制器或操作方法的安全安全访问控制,请使用操作筛选器。 例如:。
public class ClientIpCheckActionFilter : ActionFilterAttribute
{
private readonly ILogger _logger;
private readonly string _safelist;
public ClientIpCheckActionFilter(string safelist, ILogger logger)
{
_safelist = safelist;
_logger = logger;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
_logger.LogDebug("Remote IpAddress: {RemoteIp}", remoteIp);
var ip = _safelist.Split(';');
var badIp = true;
if (remoteIp.IsIPv4MappedToIPv6)
{
remoteIp = remoteIp.MapToIPv4();
}
foreach (var address in ip)
{
var testIp = IPAddress.Parse(address);
if (testIp.Equals(remoteIp))
{
badIp = false;
break;
}
}
if (badIp)
{
_logger.LogWarning("Forbidden Request from IP: {RemoteIp}", remoteIp);
context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
return;
}
base.OnActionExecuting(context);
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
在中 Startup.ConfigureServices ,将操作筛选器添加到 MVC 筛选器集合。 在下面的示例中, ClientIpCheckActionFilter 添加了一个操作筛选器。 安全日志和控制台记录器实例作为构造函数参数进行传递。
services.AddScoped<ClientIpCheckActionFilter>(container =>
{
var loggerFactory = container.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<ClientIpCheckActionFilter>();
return new ClientIpCheckActionFilter(
"127.0.0.1;192.168.1.5;::1", logger);
});
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
然后,可以将操作筛选器应用到具有 [ServiceFilter] 属性的控制器或操作方法:
[ServiceFilter(typeof(ClientIpCheckActionFilter))]
[HttpGet]
public IEnumerable<string> Get()
- 1.
- 2.
- 3.
在示例应用中,操作筛选器将应用于控制器的 Get 操作方法。 当你通过发送来测试应用程序时:
HTTP GET 请求,该 [ServiceFilter] 属性验证客户端 IP 地址。 如果允许访问 Get 操作方法,则 "操作筛选器" 和 "操作" 方法将生成以下控制台输出的变体:
dbug: ClientIpSafelistComponents.Filters.ClientIpCheckActionFilter[0]
Remote IpAddress: ::1
dbug: ClientIpAspNetCore.Controllers.ValuesController[0]
successful HTTP GET
- 1.
- 2.
- 3.
- 4.
除 GET 之外的 HTTP 请求谓词将 AdminSafeListMiddleware 验证客户端 IP 地址。
总结
该案例完全可以改造成黑名单拦截。