原文链接:Client IP safelist for ASP.NET Core

作者:Damien Bowden and Tom Dykstra

译者:Lamond Lu

本篇博文中展示了如何在ASP.NET Core应用程序中设置IP白名单验证的3种方式。

你可以使用一下3种方式:

  • 使用中间件检查每个请求的远程IP地址
  • 使用Action过滤器为指定的Controller或action方法添加针对远程IP地址的检查
  • 使用IPageFilter为Razor Pages应用添加针对远程IP地址的检查

查看项目源代码

白名单

这里为了简化代码,我们将IP白名单列表放置在配置文件appSettings.json中,每个IP之间使用分号分隔。

正式项目中,可以将这个列表保存在数据库中,便于管理

{
"AdminSafeList": "127.0.0.1;192.168.1.5;::1",
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

使用中间件检查每个请求的远程IP地址

这里我们首先添加一个中间件AdminSafeListMiddleware

public class AdminSafeListMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<AdminSafeListMiddleware> _logger;
private readonly string _adminSafeList; public AdminSafeListMiddleware(
RequestDelegate next,
ILogger<AdminSafeListMiddleware> logger,
string adminSafeList)
{
_adminSafeList = adminSafeList;
_next = next;
_logger = logger;
} public async Task Invoke(HttpContext context)
{
if (context.Request.Method != "GET")
{
var remoteIp = context.Connection.RemoteIpAddress;
_logger.LogDebug($"Request from Remote IP address: {remoteIp}"); string[] ip = _adminSafeList.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.LogInformation(
$"Forbidden Request from Remote IP address: {remoteIp}");
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return;
}
} await _next.Invoke(context); }
}

代码解释:

  • 这里在AdminSafeListMiddleware的构造函数中,我们传入了从配置文件中读取的IP白名单列表
  • 当请求进入当前中间件时,我们使用当前请求上下文的context.Connection.RemoteIpAddress获取到了客户端的IP
  • 如果客户端IP存在于IP白名单列表中,就运行下一个中间件,否则就直接返回401状态码。
  • 这里源代码中,只过滤了非GET请求,如果针对GET请求也需要启动IP白名单,可以去掉这个判断。

然后我们需要在Startup.cs文件的Configure方法中将中间件添加到ASP.NET Core的中间件管道中。

public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddNLog(); app.UseStaticFiles(); app.UseMiddleware<AdminSafeListMiddleware>(
Configuration["AdminSafeList"]);
app.UseMvc();
}

注意: 这里我们在注册中间件的时候,传入了从配置文件中读取的IP白名单。

使用Action过滤器

如果你只是希望为某些特性的Controller或Action方法添加IP白名单,你可以使用Action过滤器。

这里我们首先添加一个新类ClientIdCheckFilter, 它继承自ActionFilterAttribute

 public class ClientIdCheckFilter : ActionFilterAttribute
{
private readonly ILogger _logger;
private readonly string _safelist; public ClientIdCheckFilter
(ILoggerFactory loggerFactory, IConfiguration configuration)
{
_logger = loggerFactory.CreateLogger("ClientIdCheckFilter");
_safelist = configuration["AdminSafeList"];
} public override void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation(
$"Remote IpAddress: {context.HttpContext.Connection.RemoteIpAddress}"); var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
_logger.LogDebug($"Request from Remote IP address: {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.LogInformation(
$"Forbidden Request from Remote IP address: {remoteIp}");
context.Result = new StatusCodeResult(401);
return;
} base.OnActionExecuting(context);
}
}

这里代码逻辑和前面中间的基本一样,主要的区别是

  • 这里我们是从IP白名单,我们是从IConfiguration对象中手动获取的
  • 这里我们复写了OnActionExecuting方法,如果当前客户端 IP存在于白名单中,我们就调用基类OnActionExecuting方法,执行当前Action请求,否则就返回一个401状态码
  • 这里没有针对请求类型的判断,所以指定当前过滤器的Action,GET请求也会受到白名单的限制

第二步,我们需要将这action过滤器添加到服务容器中。

public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ClientIdCheckFilter>(); services.AddMvc(options =>
{
options.Filters.Add
(new ClientIdCheckPageFilter
(_loggerFactory, Configuration));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

第三步,我们可以在Action方法声明处添加ServiceFilter特性,传入的参数是我们之前定义好的ClientIdCheckFilter

例:

[ServiceFilter(typeof(ClientIdCheckFilter))]
[HttpGet]
public IEnumerable<string> Get()

使用IPageFilter

Razor Pages应用是ASP.NET Core 2.0中新引入的功能,它是ASP.NET Core Mvc的一个子集。

如果希望Razor Pages应用支持IP白名单,我们需要创建一个新类ClientIdCheckPageFilter, 它实现了IPageFilter接口.

public class ClientIdCheckPageFilter : IPageFilter
{
private readonly ILogger _logger;
private readonly string _safelist; public ClientIdCheckPageFilter
(ILoggerFactory loggerFactory, IConfiguration configuration)
{
_logger = loggerFactory.CreateLogger("ClientIdCheckPageFilter");
_safelist = configuration["AdminSafeList"];
} public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
{
_logger.LogInformation(
$"Remote IpAddress: {context.HttpContext.Connection.RemoteIpAddress}"); var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
_logger.LogDebug($"Request from Remote IP address: {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.LogInformation(
$"Forbidden Request from Remote IP address: {remoteIp}");
context.Result = new StatusCodeResult(401);
return;
}
} public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
{
} public void OnPageHandlerSelected(PageHandlerSelectedContext context)
{
}
}

这里的代码实现和IActionFilter的实现基本一样,唯一的区别是代码放在了OnPageHandlerExecuting的实现中。

第二步,我们还是需要将ClientIdCheckPageFilter添加到MVC的过滤器集合中。

public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ClientIdCheckFilter>(); services.AddMvc(options =>
{
options.Filters.Add
(new ClientIdCheckPageFilter
(_loggerFactory, Configuration));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

总结

本篇我们讲解了在ASP.NET Core中启用IP白名单验证的3种方式

  • 使用中间件检查每个请求的远程IP地址
  • 使用Action过滤器为指定的Controller或action方法添加针对远程IP地址的检查
  • 使用IPageFilter为Razor Pages应用添加针对远程IP地址的检查

如何为ASP.NET Core设置客户端IP白名单验证的更多相关文章

  1. ASP.NET Core获取客户端IP地址

    1.在ConfigureServices注入IHttpContextAccessor // ASP.NET Core 2.1的注入方式 //services.AddHttpContextAccesso ...

  2. 如何为ASP.NET Core的强类型配置对象添加验证

    原文: Adding validation to strongly typed configuration objects in ASP.NET Core 作者: Andrew Lock 译文: La ...

  3. ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 设置和初始化数据库 上一章节中我们已经设置和配置好了 EF ...

  4. asp dotnet core 支持客户端上传文件

    本文告诉大家如何在 asp dotnet core 支持客户端上传文件 新建一个 asp dotnet core 程序,创建一个新的类,用于给客户端上传文件的信息 public class Kanaj ...

  5. 创建ASP.NET Core MVC应用程序(6)-添加验证

    创建ASP.NET Core MVC应用程序(6)-添加验证 DRY原则 DRY("Don't Repeat Yourself")是MVC的设计原则之一.ASP.NET MVC鼓励 ...

  6. Asp.net Core, 基于 claims 实现权限验证 - 引导篇

    什么是Claims? 这个直接阅读其他大神些的文章吧,解释得更好. 相关文章阅读: http://www.cnblogs.com/JustRun1983/p/4708176.html http://w ...

  7. Data Lake Analytics IP白名单设置攻略

    当我们成功开通了 DLA 服务之后,第一个最想要做的事情就是登录 DLA 数据库.而登录数据库就需要一个连接串.下面这个页面是我们首次开通 DLA 之后的界面,在这里我们要创建一个服务访问点. 在上面 ...

  8. 微信公众平台三种IP白名单场景及设置问题

    在开发使用微信公众平台时,目前遇到有三处需要配置IP白名单. 1.微信公众平台,“获取access_token”接口新增IP白名单保护,官网:https://mp.weixin.qq.com/cgi- ...

  9. linux ip白名单、防火墙白名单 设置

    http://blog.csdn.net/catoop/article/details/50476099 登录信息在 /var/log/secure linux ip白名单 配置文件:/etc/hos ...

随机推荐

  1. Ubuntu16.04下安装Chrome出现“未安装软件包 libappindicator1”问题的解决办法

    1. 强制安装chrome sudo dpkg -i google-chrome-stable_current_i386.deb --force 2. 补齐依赖 sudo apt-get instal ...

  2. 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码

    部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...

  3. Python 可视化工具 Matplotlib

    英文出处:Chris Moffitt. Matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型的2D图表和一些基本的3D图表.本文主要介绍了在学习Matplotlib时 ...

  4. 【最小生成树】UVA1494Qin Shi Huang's National Road System秦始皇修路

    Description During the Warring States Period of ancient China(476 BC to 221 BC), there were seven ki ...

  5. noip 2015 斗地主 大爆搜!!!

    反正肯定是大模拟 但是每一个可以出的牌都搜一定不是最优的 考虑最特殊的出牌方案:顺子(单,对,三) 每一种方案再加上暴力贪心打出剩下的牌的步数 #include<cstdio> #incl ...

  6. POJ_1066_Treasure Hunt_判断线段相交

    POJ_1066_Treasure Hunt_判断线段相交 Description Archeologists from the Antiquities and Curios Museum (ACM) ...

  7. iOS 社交化分享功能

    iOS 开发过程中可能会遇到需要进行第三方分享的需求,比如向QQ,微信,微博等分享 如下图 我们今天要讲到的方式是使用了一个第三方工具: http://www.sharesdk.cn 一,注册账号 去 ...

  8. linux内核参数注释与优化

    目录 1.linux内核参数注释 2.两种修改内核参数方法 3.内核优化参数生产配置 参数解释由网络上收集整理,常用优化参数对比了网上多个实际应用进行表格化整理,使查看更直观. 学习linux也有不少 ...

  9. 【JVM虚拟机】(8)--深入理解Class中--方法、属性表集合

    #[JVM虚拟机](8)--深入理解Class中--方法.属性表集合 之前有关class文件已经写了两篇博客: 1.[JVM虚拟机](5)---深入理解JVM-Class中常量池 2.[JVM虚拟机] ...

  10. CSharpGL(50)使用Assimp加载骨骼动画

    CSharpGL(50)使用Assimp加载骨骼动画 在(http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html)介绍了C++用Asism ...