Asp.Net防止恶意刷新网页
作者:C/S原创  发布日期:2011/03/17 23:22:46
Asp.Net防止恶意刷新网页, 特别是从服务器读取数据的页面。


页面刷新控制器


using System;

using System.Collections.Generic;

using System.Text;

using System.Web.UI;

 

namespace CSFramework.BLL

{

    /// <summary>

    /// 页面刷新控制器.

    /// Session[Tag]="[FirstRefreshTime];[RefreshCounts];"

    ///    比如: "2008-01-01 14:23:00;2"  说明:2008-01-01 14:23:00访问网页,且刷新了2

    ///          "2008-01-01 14:23:00;5;Y"  说明:2008-01-01 14:23:00访问网页,且刷新了5.当标记为"Y",60秒后才能刷新网页。

    /// </summary>

    public class PageRefreshCounter

    {

        private int _delaySeconds = 30;//预设60秒后刷新网页

        private int _refreshBetween = 15;//在设定时间内刷新超出多少次.

        private int _refreshCountMax = 5;//在设定时间内刷新不超出指定次数.

 

        private static PageRefreshCounter _Instance = null;

        public static PageRefreshCounter Instance

        {

            get

            {

                if (_Instance == null)

                {

                    int delaySeconds = 60;

                    int refreshBetween = 3;

                    int refreshCountMax = 4;

 

                    _Instance = new PageRefreshCounter(delaySeconds, refreshBetween, refreshCountMax);

                }

 

                return _Instance;

            }

        }

 

        public void SetLock(Page curPage, bool isLock)

        {

            string mark = isLock ? "Y" : "N";

            string sid = GetRefreshSessionID(curPage);

            string tag = ConvertEx.ToString(curPage.Session[sid]);

            string[] sps = tag.Split(new char[] { char.Parse(";") });

            curPage.Session[sid] = sps[0] + ";" + sps[1] + ";" + mark;

        }

 

        //是否恶意刷新.10秒内刷新>3次视为恶意刷新.

        public bool IsDangerousRefresh(Page curPage)

        {

            string tag = ConvertEx.ToString(curPage.Session[GetRefreshSessionID(curPage)]);

 

            string[] sps = tag.Split(new char[] { char.Parse(";") });

            DateTime loadtime = DateTime.Parse(sps[0].ToString());

            TimeSpan span = DateTime.Now - loadtime; //最后一次时间与当前时间对比

 

            //网页被标记为恶意刷新

            if (sps.Length == 3 && sps[2] == "Y")

            {

                if (span.TotalSeconds > _delaySeconds)

                    return false;

                else

                    return true;

            }

 

            int counter = int.Parse(sps[1]);

 

            bool isDangerousRefresh = ((span.TotalSeconds <= _refreshBetween) && (counter >= _refreshCountMax));

            return isDangerousRefresh;

        }

 

        //构造器.传入当前网页对象及延时秒数

        public PageRefreshCounter(int delaySeconds, int refreshBetween, int refreshCountMax)

        {

            _delaySeconds = delaySeconds;

            _refreshBetween = refreshBetween;

            _refreshCountMax = refreshCountMax;

        }

 

        //当访问者恶新页面而暂时中断访问页面.当系统时间超出延时时间,打开页面访问权限.

        public void UpdateDelayCounter(Page curPage)

        {

            string tag = ConvertEx.ToString(curPage.Session[GetRefreshSessionID(curPage)]);

            if (tag == string.Empty)

            {

                ResetCount(curPage, DateTime.Now, 1);

                return;

            }

 

            string[] sps = tag.Split(new char[] { char.Parse(";") });

            DateTime loadtime = DateTime.Parse(sps[0].ToString());

            TimeSpan span = DateTime.Now - loadtime;

 

            if (sps.Length == 3 && sps[2] == "Y")

            {

                if (span.TotalSeconds > _delaySeconds)//超出60s延时,重设

                    this.ResetCount(curPage, DateTime.Now, 1);

                else

                    return;

            }

 

            if (span.TotalSeconds > _refreshBetween) //计数器超界,重设

                ResetCount(curPage, DateTime.Now, 1);

            else

                AddCounter(curPage);

        }

 

        //获取页面刷新控制器在Session内的标识ID

        private string GetRefreshSessionID(Page curPage)

        {

            return "RFC_" + curPage.GetType().Name;//Refresh Counter

        }

 

        //增加刷新记数器

        private void AddCounter(Page curPage)

        {

            string id = GetRefreshSessionID(curPage);

            string tag = ConvertEx.ToString(curPage.Session[id]);

 

            if (tag == null)

                ResetCount(curPage, DateTime.Now, 1);

            else

            {

                string[] sps = tag.Split(new char[] { char.Parse(";") });

                int add = ConvertEx.ToInt(int.Parse(sps[1])) + 1;

                tag = sps[0] + ";" + add.ToString();

                curPage.Session[id] = tag;

            }

        }

 

        //重设计数器

        private void ResetCount(Page curPage, DateTime refreshTime, int count)

        {

            string tag = refreshTime.ToString("yyyy-MM-dd HH:mm:ss") + ";" + count.ToString();

            curPage.Session[GetRefreshSessionID(curPage)] = tag;

        }

 

    }

}


设计一个页面基类:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace CSFramework.BLL

{

 

    /// <summary>

    /// 刷新页面计数器.

    /// </summary>

    public class PageBaseRefreshCounter : PageBase

    {

        /// <summary>

        /// 当统计数大于限制的次数,是否要跳到消息页

        /// </summary>

        protected bool _FireShowMessage = true;

 

        protected override void OnPreLoad(EventArgs e)

        {

            if (!IsPostBack)

            {

                bool restrictRefresh = true;

                if (restrictRefresh == true)

                {

                    PageRefreshCounter.Instance.UpdateDelayCounter(this);

                    if (PageRefreshCounter.Instance.IsDangerousRefresh(this))

                    {

                        PageRefreshCounter.Instance.SetLock(this, true); //锁定网页不可刷新.指定多少秒后才能刷新.                   

                        if (_FireShowMessage) PageMessage.ShowMessage(this, PageMessage.DANGEROUS_REFRESH);

                    }

                }

            }

 

            base.OnPreLoad(e);

        }

    }

}

 


转载请注明:本文来自C/S框架网,www.csframework.com

上一篇 下一篇