程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Winform開發框架之權限管理系統改進經驗總結(3)系統登錄黑白名單的實現

Winform開發框架之權限管理系統改進經驗總結(3)系統登錄黑白名單的實現

編輯:關於.NET

在一般的權限系統裡面,可能經常會看到系統的黑名單或者白名單的攔截功能。在一般權限系統裡面 ,常見的黑名單就是禁止用戶在某些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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved