ASP.NET網站限制訪問頻率

      最近做了一個免費發短信的小網站(http://freesms.cloudapp.net/),但發現最近有人破解了我的驗證碼,以每3秒/條的速度用我的短信服務來發他的廣告。更換驗證碼程序和過濾關鍵字只是治標不治本的方法,爲了徹底阻止此類事件的發生,我們還是來看一下怎樣通過優化程序來實現。

     其實同樣的程序除了防止別人濫發請求以外,還對預防拒絕服務(DoS)攻擊同樣適用哦。不妨來看看。

     基本目標:限制同一IP訪問網站的頻率。比如,我們限制爲每240分鐘來自同一IP的用戶最多隻能夠訪問首頁40次、其他頁面200次。

     比如您現在可以打開http://freesms.cloudapp.net/ 這個網站試一試,刷新40次,就可以發現您在4小時內無法再次訪問到正確的網站內容了。

     基本思想

  1.  
    1. 用HttpContext.Cache記錄訪問次數
    2. 將IP值與用戶訪問方式作爲共同的Key,可以對用戶的不同訪問方式做不同的限制。
    3. 超出限額時調用Response.End()。

    具體代碼:

        一、   定義持續時間

               在本例中,我們使用240分鐘作爲一次限制的時間。

  1.  
    private const int DURATION = 240   

        二、定義訪問方式枚舉

    針對不同的訪問方式進行不同的限制。在本例中,我們只區分兩種訪問方式:正常訪問與PostBack。在正常應用中,您還可以根據需要增加訪問不同頁面的限制。

     public enum ActionTypeEnum
         {
             Normal=40,
             Postback=100
         }

         三、判斷邏輯

  1.  
    1.  
      1. 在某IP第一次採用某種訪問方式進行訪問時,增加Cache的Key=訪問方式+IP,返回True
      2. 如果Key已經存在,增加訪問次數,返回True
      3. 如果超出次數,返回False
          public static bool IsValid(ActionTypeEnum actionType)
            {
                HttpContext context = HttpContext.Current;
                if (context.Request.Browser.Crawler) return false;
                string key = actionType.ToString() + context.Request.UserHostAddress;

                int hit = (Int32)(context.Cache[key] ?? 0);
                if (hit > (Int32)actionType) return false;
                else hit++;

                if (hit == 1)
                {
                    context.Cache.Add(key, hit, null, DateTime.Now.AddMinutes(DURATION), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);

                }
                else
                {
                    context.Cache[key] = hit;
                }
                return true;
            }

             四、在頁面中調用

      判斷函數需要在頁面的OnInit方法中調用。在這裏需要使用一些自己定義的邏輯,來進行不同訪問方式的判斷。下面的例子是一個最簡單的,只區分正常訪問與Postback。

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if (!IsPostBack)
    {
        if (!ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Normal))
        {
            Response.Write("您發送得太頻繁,被系統判斷爲廣告。廣告或其他定製業務請聯繫郵箱[email protected],謝謝。- http://freesms.cloudapp.net");
            Response.End();
        }
    }
    else
    {
        if (!ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Postback))
        {
            Response.Write("您發送得太頻繁,被系統判斷爲廣告。廣告或其他定製業務請聯繫郵箱[email protected],謝謝。- http://freesms.cloudapp.net");
            Response.End();
        }
    }
}

 

PS: 敵人總是狡詐的 ,後來我又發現那個人通過使用代理來變換IP ,繼續通過我的服務發送廣告。這就要繼續優化程序了,比如把廣告內容的md5也作爲key記錄下來。也許您也一樣,需要面對各種各樣的“敵情”。呵呵,希望本文對您有所幫助!

發佈了32 篇原創文章 · 獲贊 4 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章