.NET 6后端如何仅允许前端宿主IP访问,屏蔽其他IP?
.NET 6后端获取前端宿主IP实现IP白名单的解决方案
问题根源
你的后端拿到客户端家庭IP而非前端宿主IP,核心原因是请求经过了反向代理、CDN或云负载均衡这类中间层。这些中间件会将原始请求的源IP(前端宿主IP)放在X-Forwarded-For或X-Real-IP这类请求头中,而.NET默认只会读取直接连接的客户端IP(也就是中间层的IP)。
解决方案步骤
1. 配置.NET信任代理并解析转发IP头
在Program.cs中添加ForwardedHeaders中间件,让.NET识别并信任代理转发的IP头,自动将HttpContext.Connection.RemoteIpAddress设置为真实的前端宿主IP:
builder.Services.Configure<ForwardedHeadersOptions>(options => { // 启用解析X-Forwarded-For和X-Forwarded-Proto头 options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 添加信任的代理IP/IP段(比如你的负载均衡、CDN的IP) // 示例:添加单个代理IP options.KnownProxies.Add(IPAddress.Parse("192.168.1.100")); // 示例:添加IP段(比如云服务商的回源IP段) options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 24)); // 开发环境可临时添加回环地址,生产环境务必删除 // options.KnownProxies.Add(IPAddress.Loopback); }); // 注意:必须在UseRouting之前调用UseForwardedHeaders app.UseForwardedHeaders(); app.UseRouting();
2. 调整IP白名单校验逻辑
配置完成后,HttpContext.Connection.RemoteIpAddress会返回前端宿主的真实IP,直接基于这个值做白名单校验即可。
示例:通过授权策略实现IP白名单
// 注册授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("FrontendHostOnly", policy => { policy.RequireAssertion(context => { // 替换为你的前端宿主IP var allowedFrontendIp = IPAddress.Parse("10.1.1.10"); // 考虑IPv6兼容,可同时添加IPv6地址判断 return context.Connection.RemoteIpAddress?.Equals(allowedFrontendIp) ?? false; }); }); }); // 在需要保护的控制器/接口上应用策略 [ApiController] [Route("api/[controller]")] [Authorize(Policy = "FrontendHostOnly")] public class DataController : ControllerBase { // 接口逻辑 }
也可以通过自定义中间件实现全局校验:
app.Use(async (context, next) => { var allowedIp = IPAddress.Parse("10.1.1.10"); if (!context.Connection.RemoteIpAddress.Equals(allowedIp)) { context.Response.StatusCode = StatusCodes.Status403Forbidden; await context.Response.WriteAsync("Forbidden: Unauthorized IP"); return; } await next(); });
3. 安全与测试注意事项
- 禁止信任未知代理:生产环境绝对不能开启
options.AllowUnknownProxies,必须明确指定KnownProxies或KnownNetworks,否则攻击者可伪造X-Forwarded-For头绕过校验。 - CDN/负载均衡场景:如果前端部署在CDN上,需要将CDN的回源IP段全部加入
KnownNetworks,同时把这些回源IP加入白名单(因为CDN会用固定IP段回源请求后端)。 - 测试验证:可在接口中打印调试信息确认IP是否正确:
[HttpGet("test-ip")] public IActionResult TestIp() { var remoteIp = HttpContext.Connection.RemoteIpAddress?.ToString(); var forwardedFor = Request.Headers["X-Forwarded-For"].ToString(); return Ok(new { RemoteIp = remoteIp, XForwardedFor = forwardedFor }); }
内容的提问来源于stack exchange,提问作者FX_Sektor
相关产品推荐
相关产品推荐

