如何为ASP.NET Core设置客户端IP白名单验证
原文链接: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白名单验证的更多相关文章
- ASP.NET Core获取客户端IP地址
1.在ConfigureServices注入IHttpContextAccessor // ASP.NET Core 2.1的注入方式 //services.AddHttpContextAccesso ...
- 如何为ASP.NET Core的强类型配置对象添加验证
原文: Adding validation to strongly typed configuration objects in ASP.NET Core 作者: Andrew Lock 译文: La ...
- ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 设置和初始化数据库 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 设置和初始化数据库 上一章节中我们已经设置和配置好了 EF ...
- asp dotnet core 支持客户端上传文件
本文告诉大家如何在 asp dotnet core 支持客户端上传文件 新建一个 asp dotnet core 程序,创建一个新的类,用于给客户端上传文件的信息 public class Kanaj ...
- 创建ASP.NET Core MVC应用程序(6)-添加验证
创建ASP.NET Core MVC应用程序(6)-添加验证 DRY原则 DRY("Don't Repeat Yourself")是MVC的设计原则之一.ASP.NET MVC鼓励 ...
- Asp.net Core, 基于 claims 实现权限验证 - 引导篇
什么是Claims? 这个直接阅读其他大神些的文章吧,解释得更好. 相关文章阅读: http://www.cnblogs.com/JustRun1983/p/4708176.html http://w ...
- Data Lake Analytics IP白名单设置攻略
当我们成功开通了 DLA 服务之后,第一个最想要做的事情就是登录 DLA 数据库.而登录数据库就需要一个连接串.下面这个页面是我们首次开通 DLA 之后的界面,在这里我们要创建一个服务访问点. 在上面 ...
- 微信公众平台三种IP白名单场景及设置问题
在开发使用微信公众平台时,目前遇到有三处需要配置IP白名单. 1.微信公众平台,“获取access_token”接口新增IP白名单保护,官网:https://mp.weixin.qq.com/cgi- ...
- linux ip白名单、防火墙白名单 设置
http://blog.csdn.net/catoop/article/details/50476099 登录信息在 /var/log/secure linux ip白名单 配置文件:/etc/hos ...
随机推荐
- HTML5 & MUI 界面样式
垂直居中+自动换行 样式效果如下所示,当文字没有超出一行时,显示如“备注信息”,当文字超出一行时,显示如“维修地点” HTML代码如下: <div class="mui-input-r ...
- ps技术--批量给图片加水印
在日常的办公过程中,对于一些比较重要的文件的扫描件需要特殊处理,这时我们就需要给它们加上水印,保证它们的用途唯一,而这些扫描件很多,不可能一一给他们加水印,所以为提高工作效率,我们就可以使用一些小软件 ...
- CFile类的open方法中的参数说明
CFile::Open是在MFC里面,打开一个文件的方法. Open函数的原型如下: virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, ...
- BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图
BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大. ...
- [USACO11JAN]大陆议会The Continental Cowngress_2-sat
[USACO11JAN]大陆议会The Continental Cowngress_2-sat 题意: 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会. 议会以“每头 ...
- 作为比湖南还火的python网红,零基础要如何系统的开始学习呢?
Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定.它包含了一组完善而且容易理 ...
- CSRF Token介绍与应对策略
原文地址:点击打开链接 最近模拟登陆,发现CsrfToken是个很麻烦的问题,所以看了一下CsrfToken的一些介绍.发现这篇文章写得很不错,所以转载过来. CSRF 背景与介绍 CSRF(Cros ...
- 一起来学Spring Cloud | 第二章:服务注册和发现组件 (Eureka)
本篇文章,很浅显的一步步讲解如何搭建一个能运行的springcloud项目(带所有操作截图).相信!看完本篇之后,你会觉得springcloud搭建如此简单~~~~ 一. Eureka简介: 1.1 ...
- WebP 在减少图片体积和流量上的效果如何?MIP技术实践分享
作者 | Jackson 编辑 | 尾尾 不论是 PC 还是移动端,图片一直占据着页面流量的大头,在图片的大小和质量之间如何权衡,成为了长期困扰开发者们的问题.而 WebP 技术的出现,为解决该问题提 ...
- mongodb副本集实现
目录 1. 简单介绍 primary: secondary: arbiter: 2.系统环境设置: 3.安装mongodb 安装mongodb 增加配置文件: 添加启动脚本 3. 副本集实现: 1. ...