為應對企業對系統訪問源的管控需求,Winform開發框架權限模塊內建靈活的IP黑白名單攔截機制。本文詳細拆解其配置界面、IP段大小校驗、區間包含判斷算法、以及登錄攔截與日志記錄的完整鏈路實現。
提供列表化管理界面,支持新增、編輯、刪除規則。每條規則包含:顯示名稱、授權類型(黑名單/白名單)、IP起始地址、IP結束地址、啟用狀態等字段。


編輯保存前,必須確保「起始IP ≤ 結束IP」。框架通過擴展方法將 IPAddress 轉為 32 位無符號整數進行比較:
// IPAddress 轉整數
public static int ToInteger(this IPAddress IP) {
byte[] bytes = IP.GetAddressBytes();
return (int)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]);
}
// 比較兩個IP大小:相等0,IP1大返回1,IP1小返回-1
public static int Compare(this IPAddress IP1, IPAddress IP2) {
int ip1 = IP1.ToInteger();
int ip2 = IP2.ToInteger();
return (((ip1 - ip2) >> 0x1F) | (int)((uint)(-(ip1 - ip2)) >> 0x1F));
}
輸入校驗代碼片段:
IPAddress ip1 = IPAddress.Parse(this.txtIPStart.Text);
IPAddress ip2 = IPAddress.Parse(this.txtIPEnd.Text);
if (ip1.Compare(ip2) == 1) {
MessageDxUtil.ShowTips("IP開始地址不能大於結束地址, 請修改");
this.txtIPEnd.Focus();
result = false;
}

登錄驗證時,調用 ValidateIPAccess 判斷客戶端IP是否落在任一規則區間內。核心邏輯 IsInIp 逐字節比對:
public static bool IsInIp(string ip, string begip, string endip) {
int[] inip = GetIp(ip);
int[] begipint = GetIp(begip);
int[] endipint = GetIp(endip);
for (int i = 0; i < 4; i++) {
if (inip[i] < begipint[i] || inip[i] > endipint[i]) return false;
else if (inip[i] > begipint[i] || inip[i] < endipint[i]) return true;
}
return true;
}
// 輔助:將IP字符串解析為4字節數組
private static int[] GetIp(string ip) {
string[] parts = ip.Split('.');
return new int[] { int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3]) };
}
邏輯優先級:白名單優先放行 → 黑名單攔截 → 無匹配規則默認放行(可配置)。
登錄驗證流程中集成IP校驗:
bool ipAccess = BLLFactory<BlackIP>.Instance.ValidateIPAccess(ip, userInfo.ID);
if (ipAccess) {
// IP通過,繼續驗證密碼...
if (userPassword == userInfo.Password) {
// 記錄正常登錄日志
BLLFactory<LoginLog>.Instance.AddLoginLog(userInfo, systemType, ip, macAddr, "用戶登錄");
}
} else {
// IP被攔截,記錄拒絕日志
BLLFactory<LoginLog>.Instance.AddLoginLog(userInfo, systemType, ip, macAddr, "用戶登錄操作被黑白名單禁止登陸!");
}
攔截時前端彈出友好提示,後台自動記錄包含IP、MAC、拒絕原因的登錄日志,便於安全審計追溯。


該機制通過「配置靈活、校驗嚴謹、算法高效、日志完備」四大特性,為Winform框架提供了生產級的訪問源管控能力。IP段比較採用位運算優化,區間判斷逐字節短路,性能極佳,且代碼結構清晰易於擴展(如支持CIDR掩碼格式)。