Damian Bod 制作了一个blog post 演示如何实施中间件来处理 IP 白名单。
他给出了全局中间件或动作过滤器的例子。
无论哪种方式,您都需要将允许的 IP 地址添加到您的 appsettings.json,并对照它们检查客户端 IP 地址。
客户端 IP 地址可通过HttpContext 获得(例如context.Connection.RemoteIpAddress)。
如果你想将IP地址范围列入白名单,那么你可以使用Nuget包IPAddressRange,它支持“192.168.0.0/24”和“192.168.0.0/255.255.255.0”等多种格式,包括CIDR表达式和 IPv6。
这是一个如何在过滤器中执行此操作的示例:
appsettings.json:
{
"IPAddressWhitelistConfiguration": {
"AuthorizedIPAddresses": [
"::1", // IPv6 localhost
"127.0.0.1", // IPv4 localhost
"192.168.0.0/16", // Local network
"10.0.0.0/16", // Local network
]
}
}
IPWhiteListConfiguration.cs:
namespace My.Web.Configuration
{
using System.Collections.Generic;
public class IPWhitelistConfiguration : IIPWhitelistConfiguration
{
public IEnumerable<string> AuthorizedIPAddresses { get; set; }
}
}
IIPWhiteListConfiguration.cs:
namespace My.Web.Configuration
{
using System.Collections.Generic;
public interface IIPWhitelistConfiguration
{
IEnumerable<string> AuthorizedIPAddresses { get; }
}
}
Startup.cs:
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
// ...
services.Configure<IPWhitelistConfiguration>(
this.Configuration.GetSection("IPAddressWhitelistConfiguration"));
services.AddSingleton<IIPWhitelistConfiguration>(
resolver => resolver.GetRequiredService<IOptions<IPWhitelistConfiguration>>().Value);
// ...
}
}
ClientIPAddressFilterAttribute.cs:
namespace My.Web.Filters
{
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using NetTools;
using My.Web.Configuration;
public class ClientIPAddressFilterAttribute : ActionFilterAttribute
{
private readonly IEnumerable<IPAddressRange> authorizedRanges;
public ClientIPAddressFilterAttribute(IIPWhitelistConfiguration configuration)
{
this.authorizedRanges = configuration.AuthorizedIPAddresses
.Select(item => IPAddressRange.Parse(item));
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var clientIPAddress = context.HttpContext.Connection.RemoteIpAddress;
if (!this.authorizedRanges.Any(range => range.Contains(clientIPAddress)))
{
context.Result = new UnauthorizedResult();
}
}
}