咨询区
MartinM:
我想在一个web站点中实现ip白名单功能,在 MVC 时代我只需要在 web.config 中添加如下配置即可。
<security><ipSecurity allowUnlisted="false" denyAction="NotFound"><add allowed="true" ipAddress="XX.XX.XX.XX" subnetMask="255.255.255.0"/></ipSecurity>
</security>
但在 AspNetCore 中使用如上配置时,程序启动就会报错。
Unable to start process The web server request failed with status code 500, internal server error
很显然这个 config 配置是有问题的,请问是否有内置或者第三方的组件来实现这个功能?
回答区
Ergwun:
Damian Bod 写了一篇文章:https://damienbod.com/2016/12/18/implementing-a-client-white-list-using-asp-net-core-middleware/ 来演示如果通过中间件的方式来实现 ip 白名单功能。
他分别给了一个 全局性中间件
和 actionfilter
两种方式来实现,无论哪种方式都需要在 appsetttings.json 中配置可允许访问的 ip 列表,然后根据这个list来检查客户端的ip是否符合?client ip 可以通过 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();}}}
}
点评区
在 website 中设置ip白名单的功能非常常见,nuget上也有很多的开源中间件帮助实现,比如:ClientIpAspNetCoreIIS,我在项目中也有用到白名单的功能,只不过是做到了 nginx 层。