在一般的權限系統裡面,可能經常會看到系統的黑名單或者白名單的攔截功能。在一般權限系統裡面 ,常見的黑名單就是禁止用戶在某些IP上登錄系統,白名單就是允許用戶只在某些IP上登錄系統。本隨 筆主要介紹在我的權限系統裡面,如何實現這個黑白名單的功能,以及介紹在其中應用到的IP對比操作 ,IP段判斷等操作代碼。
1、黑白名單的配置
要完成黑名單的攔截和白名單的放行,我們需要進行名單的配置操作,我們把相關的配置放到列表裡 面進行展示,可以添加多個黑名單或者白名單,如下界面所示。
可以單擊新建按鈕進行添加一條記錄,或者在已有記錄上雙擊黑白名單可以進行編輯,界面如下所示 。
2、IP段的錄入和對比
在上面的IP輸入中,我們需要確認IP段的起始地址小於結束地址,否則我們對比的時候,就可能發生 混亂,因此需要在用戶輸入的時候進行確認,也就是IP地址的大小對比關系。
輸入內容的檢查代碼如下所示。
/// <summary> /// 實現控件輸入檢查的函數 /// </summary> /// <returns></returns> public override bool CheckInput() { bool result = true;//默認是可以通過 #region MyRegion if (this.txtName.Text.Trim().Length == 0) { MessageDxUtil.ShowTips("請輸入顯示名稱"); this.txtName.Focus(); result = false; } else if (this.txtAuthorizeType.Text.Length == 0) { MessageDxUtil.ShowTips("請選擇授權類型"); this.txtAuthorizeType.Focus(); result = false; } else if (this.txtIPStart.Text.Length == 0) { MessageDxUtil.ShowTips("請輸入IP起始地址"); this.txtIPStart.Focus(); result = false; } else if (this.txtIPEnd.Text.Length == 0) { MessageDxUtil.ShowTips("請輸入IP結束地址"); this.txtIPEnd.Focus(); result = false; } 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; } #endregion return result; }
上面代碼的IP地址的Compare函數,其實是我的擴展方法,注釋如下所示。
IP地址的對比操作,其實就是把IP文本轉換整形數值及性能對比,Compare擴展方法的定義代碼如下 所示。
/// <summary> /// IP地址轉換為INT類型 /// </summary> /// <param name="IP">IP地址</param> /// <returns></returns> public static int ToInteger(this IPAddress IP) { int result = 0; byte[] bytes = IP.GetAddressBytes(); result = (int)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]); return result; } /// <summary> /// 比較兩個IP的大小。如果相等返回0,如果IP1大於IP2返回1,如果IP1小於IP2返回-1。 /// </summary> /// <param name="IP1">IP地址1</param> /// <param name="IP2">IP地址2</param> /// <returns>如果相等返回0,如果IP1大於IP2返回1,如果IP1小於IP2返回-1。 </returns> 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)); }
3、IP段的判斷
無論是黑名單還是白名單,我們都要實現對IP段的判斷,也就是給定一個IP起始地址和結束地址,構 成的IP段,我們要判斷用戶登陸的IP是否在這個區間裡面。
bool ipAccess = BLLFactory<BlackIP>.Instance.ValidateIPAccess(ip, userInfo.ID); if (ipAccess) { ........................ if (userPassword == userInfo.Password) { ...................... //記錄用戶登錄日志 BLLFactory<LoginLog>.Instance.AddLoginLog(userInfo, systemType, ip, macAddr, "用戶登錄"); } } else { BLLFactory<LoginLog>.Instance.AddLoginLog(userInfo, systemType, ip, macAddr, "用戶登錄操作被黑白名單禁止登陸!"); }
在ValidateIPAccess函數裡面,除了白名單優先於黑名單的邏輯外,主要的邏輯判斷就是判斷指定的 IP是否落在IP段裡面,這個邏輯可以通過下面的方法進行判斷實現。
/// 檢測指定的IP地址是否在兩個IP段中 /// </summary> /// <param name="ip">指定的IP地址</param> /// <param name="begip">起始ip</param> /// <param name="endip">結束ip</param> /// <returns></returns> public static bool IsInIp(string ip, string begip, string endip) { int[] inip, begipint, endipint = new int[4]; inip = GetIp(ip); begipint = GetIp(begip); 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; }
查看本欄目
4、系統登錄攔截效果
系統攔截IP登錄後,會記錄一條日志到登錄日志裡面,如下所示。
伍華聰 http://www.iqidi.com