C#进阶-基于.NET Framework 4.x框架实现ASP.NET WebForms项目IP拦截器

article/2025/7/18 22:00:55

在这篇文章中,我们将探讨如何在 ASP.NET WebForms 中实现IP拦截器,以便在 ASMX Web 服务方法HTTP 请求 中根据IP地址进行访问控制。我们将使用自定义的 SoapExtensionIHttpModule 来实现这一功能,并根据常用的两种文本传输协议:SOAP协议HTTP协议进行分别讲解。


一、创建ASMX接口文件

首先,我们创建一个 ASP.NET WebForms 项目,创建 TestAsmxProject.Asmx 文件,并定义里面的 WebService 服务。
如果不会创建 ASMX 文件,可以参考我的上一篇文章:C#进阶-ASP.NET WebForms调用ASMX的WebService接口。

TestAsmxProject.Asmx 代码如下:

using System.Web.Services;namespace TestAsmxProject.Asmx
{/// <summary>/// Test 的摘要说明/// </summary>[WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 [System.Web.Script.Services.ScriptService]public class Test : System.Web.Services.WebService{[WebMethod]public string HelloWorld(){return "Hello World";}[WebMethod(Description = "计算两个数的和")]public int Add(int a, int b){return a + b;}}
}

从这个类我们可以看到,目前是有两个 WebService 方法:HelloWorld 方法和 Add方法。调用 HelloWorld 方法会返回 "Hello World" 字符串;用 Add 方法,需要传入 ab 两个参数,会返回 ab 相加的和。


二、基于SOAP协议的拦截器实现

创建一个自定义的 SoapExtension 来实现IP拦截。我们还需要一个自定义属性来指定允许的IP地址。

1. 创建IpFilterAttribute类

新建 Filter 文件夹,再在 Filter 文件夹里新建 SOAP 文件夹。

请添加图片描述

SOAP 文件夹里创建 IpFilterAttribute 类。

在这里插入图片描述

在这里插入图片描述

IpFilterAttribute.cs 代码如下:

using System;
using System.Web.Services.Protocols;namespace TestAsmxProject.Filter.SOAP
{[AttributeUsage(AttributeTargets.Method)]public class IpFilterAttribute : SoapExtensionAttribute{public override Type ExtensionType => typeof(IpFilter);public override int Priority { get; set; }public string[] AllowedIps { get; private set; }public IpFilterAttribute(params string[] ips){AllowedIps = ips.Length > 0 ? ips : null;Priority = 1;}} 
}

在这里插入图片描述


2. 创建基于SoapExtension的IpFilter注解类

创建 IpFilter.cs,继承 SoapExtension

在这里插入图片描述

IpFilter.cs 代码如下:

using System;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Services.Protocols;namespace TestAsmxProject.Filter.SOAP
{public class IpFilter : SoapExtension{private string[] allowedIps;public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute){var ipFilterAttribute = attribute as IpFilterAttribute;return ipFilterAttribute?.AllowedIps;}public override object GetInitializer(Type serviceType){return null;}public override void Initialize(object initializer){allowedIps = initializer as string[];}public override void ProcessMessage(SoapMessage message){switch (message.Stage){case SoapMessageStage.BeforeSerialize:break;case SoapMessageStage.AfterSerialize:break;case SoapMessageStage.BeforeDeserialize:CheckIpValidation(message);break;case SoapMessageStage.AfterDeserialize:break;}}private void CheckIpValidation(SoapMessage message){try{string clientIp = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];if (string.IsNullOrEmpty(clientIp)){clientIp = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];}if (!IsValidIp(clientIp)){HttpContext.Current.Response.Clear();HttpContext.Current.Response.StatusCode = 403;HttpContext.Current.Response.ContentType = "text/plain";HttpContext.Current.Response.Write("Access denied: Your IP address is not allowed.");HttpContext.Current.Response.End();}}catch (Exception ex){throw;}}private bool IsValidIp(string ip){string configIps = ConfigurationManager.AppSettings["IpWhiteList"];string[] configAllowedIps = !string.IsNullOrWhiteSpace(configIps)? configIps.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries): new string[] { };var allAllowedIps = (allowedIps == null ? new string[] { } : allowedIps).Concat(configAllowedIps).ToArray();return allAllowedIps.Any(allowIp => ip == allowIp);}}
}

在这里插入图片描述


3. 配置web.config中IP白名单

web.config 文件中配置白名单IP列表,在 IpFilter.cs 里我们已经写过该逻辑,web.config 文件中白名单内的 IpWhiteList 里的IP是全局白名单,无论 WebService服务方法 上是否有 [IpFilter] 注解。

<configuration><appSettings><add key="IpWhiteList" value="127.0.0.1,192.168.1.1" /></appSettings>
</configuration>

4. 在WebService方法上添加注解

WebService服务方法 上使用 [IpFilter] 注解,可以定义该方法的专属IP白名单(包含 web.config 中的全局白名单),如果不设定,则仅使用 web.config 中的白名单。

加了 [IpFilter] 注解后的 TestAsmxProject.Asmx 代码如下:

using System.Web.Services;
using TestAsmxProject.Filter.SOAP;namespace TestAsmxProject.Asmx
{/// <summary>/// Test 的摘要说明/// </summary>[WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 [System.Web.Script.Services.ScriptService]public class Test : System.Web.Services.WebService{[WebMethod][IpFilter] // 不传入指定IP,使用web.config中的白名单public string HelloWorld(){return "Hello World";}[WebMethod(Description = "计算两个数的和")][IpFilter("127.0.0.1", "192.168.1.1")] // 此处为该方法的IP白名单,加上web.config中的白名单共同生效public int Add(int a, int b){return a + b;}}
}

在这里插入图片描述


三、基于HTTP协议的拦截器实现

接下来,我们创建一个基于HTTP协议的拦截器来实现IP拦截。同样,我们需要一个自定义属性来指定允许的IP地址。

1. 创建IpFilterAttribute类

新建 Filter 文件夹,再在 Filter 文件夹里新建 HTTP 文件夹。

请添加图片描述

SOAP 文件夹里创建 IpFilterAttribute 类。

在这里插入图片描述

在这里插入图片描述

IpFilterAttribute.cs 代码如下:

using System;
using System.Configuration;namespace TestAsmxProject.Filter.HTTP
{[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]public sealed class IpFilterAttribute : Attribute{public string[] AllowedIps { get; private set; }public IpFilterAttribute(params string[] ips){string configIps = ConfigurationManager.AppSettings["IpWhiteList"];var configAllowedIps = !string.IsNullOrEmpty(configIps)? configIps.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries): new string[] { };AllowedIps = new string[ips.Length + configAllowedIps.Length];ips.CopyTo(AllowedIps, 0);configAllowedIps.CopyTo(AllowedIps, ips.Length);}public bool IsAllowedIp(string userIp){return AllowedIps.Any(ip => userIp == ip);}}
}

2. 创建基于IHttpModule的IpFilter注解类

创建 IpFilter.cs,继承 IHttpModule

在这里插入图片描述

IpFilter.cs 代码如下:

using System;
using System.Linq;
using System.Reflection;
using System.Web;namespace TestAsmxProject.Filter.HTTP
{public class IpFilter : IHttpModule{public void Init(HttpApplication context){context.PreRequestHandlerExecute += new EventHandler(OnPreRequestHandlerExecute);}private void OnPreRequestHandlerExecute(object sender, EventArgs e){HttpApplication application = (HttpApplication)sender;HttpContext context = application.Context;if (context.Request.Path.Contains(".asmx")){string userIp = context.Request.UserHostAddress;string methodName = context.Request.PathInfo.Replace("/", "");Type webServiceType = GetWebServiceType(context.Request.Path);if (webServiceType != null){MethodInfo methodInfo = webServiceType.GetMethod(methodName);if (methodInfo != null){var attribute = methodInfo.GetCustomAttribute<IpFilterAttribute>();if (attribute != null && !attribute.IsAllowedIp(userIp)){context.Response.StatusCode = 403;context.Response.ContentType = "text/plain";context.Response.Write("Access denied: Your IP address is not allowed.");context.Response.End();}}}}}private Type GetWebServiceType(string path){string serviceName = path.Split('/')[2].Split('.').First();string namespacePrefix = "";string typeName = $"{namespacePrefix}.{serviceName}";Type serviceType = Type.GetType(typeName);if (serviceType == null){var assemblies = AppDomain.CurrentDomain.GetAssemblies();foreach (var assembly in assemblies){serviceType = assembly.GetType(typeName);if (serviceType != null){break;}}}return serviceType;}public void Dispose() { }}
}

3. 配置web.config中白名单和模块

web.config 文件中配置白名单IP列表,在 IpFilter.cs 里我们已经写过该逻辑,web.config 文件中白名单内的 IpWhiteList 里的IP是全局白名单,无论 WebService服务方法 上是否有 [IpFilter] 注解。

<configuration><appSettings><add key="IpWhiteList" value="127.0.0.1,192.168.1.1" /></appSettings><system.web><httpModules><add name="IpFilter" type="TestAsmxProject.Filter.HTTP.IpFilter"/></httpModules></system.web><system.webServer><validation validateIntegratedModeConfiguration="false" /><modules runAllManagedModulesForAllRequests="true"><add name="IpFilter" type="TestAsmxProject.Filter.HTTP.IpFilter"/></modules></system.webServer>
</configuration>

4. 在WebService方法上添加注解

WebService服务方法 上使用 [IpFilter] 注解,可以定义该方法的专属IP白名单(包含 web.config 中的全局白名单),如果不设定,则仅使用 web.config 中的白名单。

加了 [IpFilter] 注解后的 TestAsmxProject.Asmx 代码如下:

using System.Web.Services;
using TestAsmxProject.Filter.HTTP;namespace TestAsmxProject.Asmx
{/// <summary>/// Test 的摘要说明/// </summary>[WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 [System.Web.Script.Services.ScriptService]public class Test : System.Web.Services.WebService{[WebMethod][IpFilter] // 不传入指定IP,使用web.config中的白名单public string HelloWorld(){return "Hello World";}[WebMethod(Description = "计算两个数的和")][IpFilter("127.0.0.1", "192.168.1.1")] // 此处为该方法的IP白名单,加上web.config中的白名单共同生效public int Add(int a, int b){return a + b;}}
}

在这里插入图片描述


四、IP拦截器实现总结

通过上述步骤,我们成功实现了在 ASP.NET WebForms 中基于IP地址的访问控制。我们分别使用自定义的 SoapExtensionIHttpModule,实现了对ASMX Web服务方法和HTTP请求的IP拦截。

1. 自定义 SoapExtension

自定义的 SoapExtension 通过重载 ProcessMessage 方法,在SOAP消息处理的不同阶段进行IP地址的验证。通过检查请求的IP地址并与允许的IP列表进行比较,我们可以在消息反序列化之前阻止不符合条件的请求,从而有效地控制对Web服务方法的访问。这种方法特别适用于基于SOAP的Web服务,能够在服务方法调用之前进行精细的访问控制。

2. 自定义 IHttpModule

自定义的 IHttpModule 通过实现 Init 方法并注册 PreRequestHandlerExecute 事件,在每个HTTP请求处理之前执行IP地址验证。通过反射获取请求对应的方法,并检查方法上的自定义属性 IpFilterAttribute,我们可以动态地对特定方法应用IP过滤规则。结合 web.config 中配置的白名单IP地址,这种方法能够灵活地扩展和维护IP访问控制规则,适用于一般的HTTP请求拦截需求。

3. 本文提供方法的实现优势

这种IP拦截器的实现方法不仅增强了应用程序的安全性,还具有良好的扩展性和可维护性。开发者可以根据具体需求,通过配置文件或代码注解灵活地管理允许的IP地址。通过将安全控制逻辑封装在自定义模块和扩展中,可以保持业务代码的简洁和可读性。

希望这篇文章对你在ASP.NET WebForms应用中的IP访问控制有所帮助。


http://www.hkcw.cn/article/vPYCauKmiD.shtml

相关文章

【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解

前言 &#x1f31f;&#x1f31f;本期讲解关于HTMLCSSJavaScript的基础知识&#xff0c;小编带领大家简单过一遍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 …

Open WebUI项目源码学习记录(从0开始基于纯CPU环境部署一个网页Chat服务)

感谢您点开这篇文章:D&#xff0c;鼠鼠我是一个代码小白&#xff0c;下文是学习开源项目Open WebUI过程中的一点笔记记录&#xff0c;希望能帮助到你&#xff5e; 本人菜鸟&#xff0c;持续成长&#xff0c;能力不足有疏漏的地方欢迎一起探讨指正&#xff0c;比心心&#xff5e…

C++家庭财务管理 全国信息素养大赛复赛决赛 C++小学/初中组 算法创意实践挑战赛 内部集训模拟题详细解析

C++家庭财务管理 全国信息素养大赛 C++复赛/决赛模拟训练题 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】1、C++专栏 电子学会C++一级历年真题解析

“雪龙2”号今起开放预约 端午假期新体验

“雪龙2”号是我国首艘自主建造的极地科学考察破冰船。6月2日起,“雪龙2”号在海南举办了为期五天的公众开放日活动,这是该船首次抵达海南并面向公众开放,为公众带来了端午假期的新体验。活动期间,公众可以预约参观科考实验室、登船大厅以及飞行平台等多个特色区域,近距离…

太原警方:李某彪被当场控制 酒后驾车冲撞他人

太原市小店警方对一起事件作出回应:6月2日0时许,李某彪酒后与他人发生口角,随后驾车冲撞与其发生争执的人员,导致商家门口部分物品受损,两名在场人员在躲避过程中轻微受伤。民警迅速到达现场并将李某彪控制。目前案件正在进一步办理中。此前有报道称,6月2日凌晨4时许,有…

MySQL学习笔记Day9(事务)

事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 举个例子&#xff0c;去银行转账的操作就是一个事务&#xff0c;比如A要…

黑龙江多地现粉色极光 梦幻奇观引关注

6月2日,黑龙江密山、佳木斯等地的网友在社交平台上分享了梦幻般的粉色极光视频。画面中,天空被渲染成粉紫色,宛如飘逸的丝带舞动,美得令人窒息,仿佛置身于童话世界。一位来自佳木斯的视频发布者兴奋地讲述了拍摄经历。他在6月1日晚9时左右来到郊区福胜村江边,支好设备,用…

外卖诗人王计兵回应新职 兼职阅读推广

近日,一则关于“外卖诗人”王计兵新职务的消息引起了网友的关注。据徐州市委宣传部发布的任前公示,王计兵拟任徐州市全民阅读促进会副会长。6月2日,王计兵确认了这一消息,并表示这个新职务是兼职,不会影响他继续做外卖员的工作。他表示自己将主要负责一些阅读推广活动。王…

河北秦皇岛市卢龙县发生2.5级地震 震源深度10公里

据中国地震台网正式测定,6月2日17时35分在河北秦皇岛市卢龙县发生2.5级地震,震源深度10公里,震中位于北纬39.96度,东经118.88度。震中5公里范围内平均海拔约50米。根据中国地震台网速报目录,震中周边200公里内近5年来共发生3级以上地震14次,其中最大一次是2020年7月12日在…

入户调查已开始 今年抽取30万人 反映人口特征与生活质量变化

国家统计局日前发布了《致人口固定样本跟访调查对象的一封信》,决定于2025年在全国范围内开展两次人口固定样本跟访调查。两次调查的标准时点分别为6月1日零时和11月1日零时,调查员将在6月1日至6月25日以及11月16日至12月5日期间入户开展调查工作。今年的人口固定样本跟访调查…

[Redis] Redis命令(2)

初次学习&#xff0c;如有错误还请指正 目录 Set命令 SortedSet类型 Set命令 Redis的Set结构与Java中的HashSet类似&#xff0c;可以看做是一个value为null的HashMap。因为也是一个hash表&#xff0c; 因此具备与HashSet类似的特征&#xff1a; 无序 元素不可重复 查找快…

开发规范1

Restful REST (REpresentational State Transfer)&#xff0c;表述性状态转换&#xff0c;它是一种软件架构风格。 传统 Restful Apifox测试工具 介绍:Apifox是一款集成了Api文档、Api调试、ApiMock、Api测试的一体化协作平台。 作用:接口文档管理、接口请求测试、Mock服务。…

2.RV1126-OPENCV Mat理解和AT函数

一.Mat概念 Mat 是整个图像存储的核心也是所有图像处理的最基础的类&#xff0c;Mat 主要存储图像的矩阵类型&#xff0c;包括向量、矩阵、灰度或者彩色图像等等。Mat由两部分组成&#xff1a;矩阵头&#xff0c;矩阵数据。矩阵头是存储图像的长度、宽度、色彩信息等头部信息&a…

梅州村民鸡舍惊现50斤重蟒蛇 警民联手成功捕获

6月1日早上6时30分,正当小朋友们开始庆祝儿童节的时候,五华县公安局丁畲派出所的值班电话突然响起。村民温先生求助称家中鸡舍出现一条大蛇,导致鸡鹅四散奔逃。接到报警后,丁畲派出所的民辅警迅速赶往现场,并联系了专业的捕蛇师傅一同前往。到达现场后,他们发现大蛇蜷缩在…

【笔记】基于 MSYS2(MINGW64)的 Poetry 虚拟环境创建指南

#工作记录 基于 MSYS2&#xff08;MINGW64&#xff09;的 Poetry 虚拟环境创建指南 一、背景说明 在基于 MSYS2&#xff08;MINGW64&#xff09;的环境中&#xff0c;使用 Poetry 创建虚拟环境是一种高效且灵活的方式来管理 Python 项目依赖。本指南将详细介绍如何在 PyChar…

波兰新总统是谁 纳夫罗茨基胜选引发关注

根据波兰国家选举委员会网站当地时间6月2日公布的统计结果,独立候选人卡罗尔纳夫罗茨基赢得了波兰总统选举,他获得了50.89%的选票,与得票率为49.11%的公民联盟候选人、华沙市长拉法尔恰斯科夫斯基展开了激烈竞争。自两周前的首轮投票后,波兰国内的选情持续胶着,反映出这个…

给散装江苏发明省内足球联赛简直天才 比赛第一,友谊第十四!

“友谊第一,比赛第二”这句口号在一场足球比赛中被戏谑地改成了“友谊第一,比赛第十四”,随后又变成了“比赛第一,友谊第十四”。这种幽默的表达方式让江苏省首届城市足球联赛迅速走红。这个被称为“苏超”的足球联赛吸引了大量观众。盐城的一场比赛有22613名观众到场,现场…

奇瑞集团前五月累销突破100万辆 销量创历史新高

奇瑞集团宣布,今年1月至5月累计销售汽车1,026,517辆,同比增长14%,创下历史最快销售速度。其中,新能源汽车销量达到287,798辆,同比增长111.5%;出口量为443,940辆,继续保持中国车企出口第一的位置。5月份,奇瑞集团共销售汽车205,732辆,同比增长9.1%。奇瑞汽车股份有限公…

江苏十三太保把足球踢出圈 热梗频出带火赛事

近日,一场名为“苏超”的足球盛事在江苏火了起来。这场赛事没有假球,只有激烈的竞争,口号是“比赛第一,友谊第十四”。这一系列的热梗不仅带火了足球赛事,也让江苏13个地市的文化旅游产业备受关注。“苏超”全称为“江苏省城市足球联赛”,由江苏省体育局与各设区市政府联…

【人工智能】deepseek七篇论文阅读笔记大纲

七篇文章看了整整五天&#xff0c;加上整理笔记和问ds优化&#xff0c;大致的框架是有了。具体的公式细节比较多&#xff0c;截图也比较麻烦&#xff0c;就不列入大纲去做笔记了。 DeepSeek-LLM&#xff1a;一切的起点&#xff0c;所以探索的东西比较多&#xff0c;包括&#x…