原文链接: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. selenium自动化测试资源整理(含所有版本chrome、chromedriver、firefox下载链接)

    今天把手头有的一些关于selenium测试的资源整理了一下,分享出来. 1. 所有版本chrome下载 是不是很难找到老版本的chrome?博主收集了几个下载chrome老版本的网站,其中哪个下载的是 ...

  2. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  3. C++11标准中常用到的各种算法汇总.

    在C++11标准中定义了很多算法,这些算法可以让我们很方便的操作各种容器和数组,这里要注意一下,这些算法操作的并非容器,而是迭代器,然后通过迭代器来操作容器中的数据,算法本身并不会关注容器中保存的数据 ...

  4. BZOJ 1260:[CQOI2007]涂色paint

    (⊙o⊙)-,常规课考试又炸了!目测此次我要完蛋了... 又玩脱了,考数学的时候装B装大了! 算了,先进入正题... 题目描述:Description假设你有一条长度为5的木版,初始时没有涂过任何颜色 ...

  5. ELK---日志分析系统

    ELK就是一套完整的日志分析系统 ELK=Logstash+Elasticsearch+Kibana 统一官网https://www.elastic.co/products ELK模块说明 Logst ...

  6. 毕业样本=[威尔士大学毕业证书]UWIC原件一模一样证书

    威尔士大学毕业证[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&am ...

  7. CSS3实例分享之多重背景的实现(Multiple backgrounds)

    CSS3的诞生为我们解决了这一问题,在CSS3里,通过background-image或者background可以为一个容器设置多张背景图像,也就是说可以把不同背景图象只放到一个块元素里. 首先我们来 ...

  8. ceph osd 自动挂载的N种情况

    直接上干货: ceph自动挂载原理 系统启动后,ceph 通过扫描所有磁盘及分区的 ID_PART_ENTRY_TYPE 与自己main.py中写死的osd ready 标识符来判断磁盘(及其分区)是 ...

  9. linux命令----查看磁盘空间

    今天用“web发布平台”发布测试的服务,两个节点中发现有一个节点没有发布成功,压测TPS始终上不去,排查后发现只有一个节点在打日志,另一个节点的服务进程都没有在运行,由此断定应该是没有发布成功,有点坑 ...

  10. HTML5网页录音和上传到服务器,支持PC、Android,支持IOS微信

    准备做一个网页版聊天界面,表情啊.图片啊.上传文件啊都应该要有,视频就算了,语音还是要的. 本文记录的是在网页上用GitHub上的Recorder进行在线录音和上传到服务器,前几天升了一下级,以后有时 ...