You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asp.Net Core 2.*中IpRestrictionModule失效咨询(原1.*版本可用)

解决Asp.Net Core 2.x中IpRestrictionModule配置失效的问题

你遇到的这个报错本质上是IIS配置层级锁定导致的,同时Asp.Net Core 2.x相比1.x,在IIS托管模式下的配置处理逻辑确实有调整——1.x用的是HttpPlatformHandler,2.x换成了AspNetCoreModuleV2,这个模块对web.config的读取规则更严格,而ipSecurity节默认在父级IIS配置中是锁定状态(overrideModeDefault="Deny"),所以直接在项目的web.config里配置就会触发这个错误。

下面给你两种解决方案,按需选择:

方案一:解锁IIS的ipSecurity配置节(继续用IpRestrictionModule)

如果你想继续依赖IIS的IpRestrictionModule来实现IP限制,需要先解锁对应的配置节:

  • 打开IIS管理器,选中你的服务器节点,在功能视图里找到配置编辑器并双击打开
  • 在顶部的“节”下拉菜单中找到system.webServer/security/ipSecurity
  • 点击右侧操作栏的解锁节,确认后保存配置
  • 回到项目的web.config,你的原有ipSecurity配置就可以正常生效了,同时要确保应用池的.NET CLR版本设置为无托管代码(Asp.Net Core是自托管模式,IIS仅做反向代理)

方案二:用Asp.Net Core原生中间件实现IP限制(更推荐)

这种方式不依赖IIS配置,跨平台性更好,也是Asp.Net Core 2.x及以后的官方推荐方案:

1. 配置转发头(如果应用在反向代理后,比如Azure App Service、Nginx)

如果你的应用部署在反向代理后面,需要先配置转发头才能获取到真实的客户端IP,在Startup.cs的ConfigureServices方法中添加:

using Microsoft.AspNetCore.HttpOverrides;

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        // 添加你的代理服务器IP,比如本地回环127.0.0.1,根据实际情况调整
        options.KnownProxies.Add(IPAddress.Parse("127.0.0.1"));
    });
    // 其他服务配置...
}

2. 添加IP限制中间件

在Startup.cs的Configure方法中,添加IP限制逻辑(注意要放在UseRouting之前):

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 先启用转发头,确保获取真实客户端IP
    app.UseForwardedHeaders();

    // 配置IP限制规则
    app.UseWhen(context => !IsIpAllowed(context.Connection.RemoteIpAddress), appBuilder =>
    {
        appBuilder.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsync("Access Denied: Your IP is not authorized to access this resource.");
        });
    });

    // 后续的中间件,比如路由、授权等...
    app.UseRouting();
    app.UseAuthorization();
    // ...
}

// 定义IP允许规则的辅助方法
private bool IsIpAllowed(IPAddress remoteIp)
{
    if (remoteIp == null) return false;

    // 处理IPv6回环,转换为IPv4格式
    string clientIp = remoteIp.ToString();
    if (clientIp == "::1") clientIp = "127.0.0.1";

    // 允许的单个IP列表
    var allowedSingleIps = new HashSet<string>
    {
        "127.0.0.1",
        "83.116.19.53"
    };
    if (allowedSingleIps.Contains(clientIp)) return true;

    // 允许的子网(示例:83.116.119.0/24)
    var allowedSubnets = new List<string>
    {
        "83.116.119.0/24"
    };
    foreach (var subnet in allowedSubnets)
    {
        if (IsInSubnet(clientIp, subnet)) return true;
    }

    return false;
}

// 检查IP是否在指定子网内的辅助方法
private bool IsInSubnet(string clientIp, string subnet)
{
    if (!IPAddress.TryParse(clientIp, out var clientAddress)) return false;
    var parts = subnet.Split('/');
    if (parts.Length != 2 || !IPAddress.TryParse(parts[0], out var subnetAddress) || !int.TryParse(parts[1], out var prefixLength))
        return false;

    var subnetMask = GetSubnetMask(prefixLength, clientAddress.AddressFamily);
    var clientNetwork = new IPAddress(clientAddress.GetAddressBytes().Zip(subnetMask.GetAddressBytes(), (a, b) => (byte)(a & b)).ToArray());
    var targetNetwork = new IPAddress(subnetAddress.GetAddressBytes().Zip(subnetMask.GetAddressBytes(), (a, b) => (byte)(a & b)).ToArray());

    return clientNetwork.Equals(targetNetwork);
}

// 获取子网掩码的辅助方法
private IPAddress GetSubnetMask(int prefixLength, AddressFamily addressFamily)
{
    int byteCount = addressFamily == AddressFamily.InterNetwork ? 4 : 16;
    var maskBytes = new byte[byteCount];
    for (int i = 0; i < prefixLength; i++)
    {
        maskBytes[i / 8] |= (byte)(1 << (7 - i % 8));
    }
    return new IPAddress(maskBytes);
}

这样配置后,不管是在IIS还是其他托管环境(比如Kestrel、Docker),IP限制逻辑都能正常工作。

内容的提问来源于stack exchange,提问作者McKabue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:03:28