ApiController的过滤器使用

1. >>>>>>>>>>>>>>>>>>>DemoController>>>>>>>>>>>>>>>>>>

using DJTWebBAL;
using DJTWebModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace WebApi.RongCloud
{
    [ControllerFilter]//过滤器,用作用户权限过滤
    public class DemoController : ApiController
    {
        [ActionFilter]//过滤器,用作访问IP次数过滤
        [HttpPost]
        public HttpResponseMessage Test()
        {
            string httpRequestMessage = string.Format("{0}","OK");
            return new HttpResponseMessage { Content = new StringContent(httpRequestMessage) };
        }

    }
}

2.>>>>>>>>>>>>>>>>>>>>>>>>>>过滤器>>>>>>>>>>>>>>>>>>>>>>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace WebApi.RongCloud
{
    public class ControllerFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);
            HttpContextBase httpcontext = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];

            string puserId = httpcontext.Request["userId"];         //获取参数信息
            string userId = httpcontext.Request.Headers["userId"];  //获取头信息
            string userPwd = httpcontext.Request.Headers["userPwd"];

            if (userId == "myid" && userPwd == "mypwd")
            {
                //账号密码正确不做任何操作!
            }
            else
            {
                //账号密码不正确,返回提示信息!
                string httpRequestMessage = string.Format("{{\"status\":\"{0}\",\"message\":\"{1}\",\"userInfo\":{2}}}", puserId, "账号密码不正确!", "[]");
                actionContext.Response = new HttpResponseMessage { Content = new StringContent(httpRequestMessage) };
            }

        }

    }


    public class ActionFilter : ActionFilterAttribute
    {
       private static Dictionary visitors = new Dictionary();
        private static int maxCount = 3;//默认最大访问次数,之后在配置文件配置
        private static long interval = 600;//默认600秒钟,之后在配置文件配置

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);
            HttpContextBase httpcontext = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];
            string serverAction=httpcontext.Request.Url.ToString();            

            string userIP = GetUserIP(httpcontext) + ":" + serverAction;
            userIP = userIP.Replace("/", "\\");
            string httpRequestMessage = string.Empty;

            Visitor vis = new Visitor();
            bool isExist = false;//是否存在
            foreach (string key in visitors.Keys)
            {
                if (key == userIP) { isExist = true; }
            }
            DateTime now = DateTime.Now;
            DateTime dt = new DateTime(1970, 1, 1);
            TimeSpan d = now - dt;
            long seconddiff = d.Ticks / 10000000;
            if (isExist)
            {
                vis = visitors[userIP];
                vis.getRequestTimeQueue().insert(seconddiff);//插入当前请求时间
                long span = vis.getRequestTimeQueue().getLast() - vis.getRequestTimeQueue().getFirst();
                if (span < interval && vis.getRequestTimeQueue().getLast() != 0)
                {
                    httpRequestMessage = string.Format("{{\"span\":\"{0}\",\"userIP\":\"{1}\"}}", span.ToString(), userIP);
                    actionContext.Response = new HttpResponseMessage { Content = new StringContent(httpRequestMessage) };                      
                }

            }
            else
            {
                ArrayTime timeQueue = new ArrayTime();
                timeQueue.setLength(maxCount);
                timeQueue.init();
                vis = new Visitor();
                vis.setUserIP(userIP);
                vis.setRequestTimeQueue(timeQueue);
                vis.getRequestTimeQueue().insert(seconddiff);
                visitors.Add(userIP, vis);
            }

            //调试使用
            //string strNow=now.ToString("yyyy-MM-dd HH:mm:ss");
            //httpRequestMessage = string.Format("{{\"now\":\"{0}\",\"userIP\":\"{1}\"}}", strNow, userIP);
            //actionContext.Response = new HttpResponseMessage { Content = new StringContent(httpRequestMessage) };
            
        }

        //服务器端获取请求用户的IP
        //::1就是IP地址,估计你是win7或 Vista的系统 或安装了IPV6,这是ipv6的本地回环地址就是ipv4中的127.0.0.1
        private string GetUserIP(HttpContextBase httpcontext)
        {
            string _userIP;
            if (httpcontext.Request.ServerVariables["HTTP_VIA"] == null)//未使用代理
            {
                _userIP = httpcontext.Request.UserHostAddress;
            }
            else//使用代理服务器
            {
                _userIP = httpcontext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            return _userIP;
        }

    }

    //下面,我们来着重讨论如何实现恶意刷新的过滤器。
    //因为我们的需求是在任何的10秒中记录请求数而不是在以10秒为一个时间段,那么就需要保证时间的连续性,
    //鉴于此需求,我们需要保存用户连续10次请求的时间,如果其最后一次的请求时间与第一次的时间差小于10秒并且次数已经达到10次,则违背设定规则,
    //我们设计了下面的类来保存用户的访问时间序列。
    public class ArrayTime
    {

        private long[] time;
        private int length = 10; //默认为十次(10s内刷新10次则违反规则)
        public ArrayTime()
        {
        }

        public void init()
        {
            time = new long[length];
        }

        public int getLength()
        {
            return this.length;
        }

        public void setLength(int len)
        {
            this.length = len;
        }

        public long getLast()
        {
            return this.time[length - 1];
        }

        public long getFirst()
        {
            return this.time[0];
        }

        public long getElement(int i)
        {
            return time[i];
        }

        public void insert(long nextTime)
        {
            if (this.getLast() != 0)//数组已经满了
            {
                //去掉首元素,将数组元素顺序前移,nextTime插到最后
                for (int i = 0; i < this.length - 1; i++)
                {
                    time[i] = time[i + 1];
                }
                this.time[length - 1] = nextTime;
            }
            else
            {
                //插到下一个,不用排序
                int j = 0;
                while (time[j] != 0)
                {
                    j++;
                }
                time[j] = nextTime;
            }
        }
    }

    //这里要注意的是,因为我们为管理员提供了规则设置的接口,所以保存时间序列的数组长度是可设定的。下面是来自客户端的访问者类的实现:
    public class Visitor
    {

        // Creates a new instance of Visitor
        //外网访问者,以用户IP作为标识
        //违反访问规则将其IP列为受限IP,拒绝访问

        private String userIP = null;
        private ArrayTime requestTimeQueue = new ArrayTime();

        public int Count;
        public Visitor()
        {
        }

        public void setUserIP(String userIP)
        {
            this.userIP = userIP;
        }

        public String getUserIP()
        {
            return this.userIP;
        }

        public void setRequestTimeQueue(ArrayTime requestTimeQueue)
        {
            this.requestTimeQueue = requestTimeQueue;
        }

        public ArrayTime getRequestTimeQueue()
        {
            return this.requestTimeQueue;
        }
    }


    //最后,也是最关键的就是我们如何来通过过滤器实现对恶意用户的请求进行屏蔽。下面是该过滤器的doFliter()方法的核心部分的实现。
 
    //---------------防止恶意刷新的过滤器--------
    //HttpServletRequest req = (HttpServletRequest)request;
    //HttpServletResponse res = (HttpServletResponse)response;
    //String sessionID = ((HttpServletRequest)request).getSession().getId();//会话ID
    //Date now =new Date();
    //Visitor vis = (Visitor) visitors.get(sessionID);//通过sessionID查找访问者,
    //if(vis!= null)//找到访问者,则说明该用户为再次访问
    //...{
    小于10秒,但访问超过10次
    //vis.getRequestTimeQueue().insert(now.getTime());//插入当前请求时间
    得到最后一次和第一次的访问时间差
    //Long span = vis.getRequestTimeQueue().getLast() - vis.getRequestTimeQueue().getFirst();
    //if(span < interval && vis.getRequestTimeQueue().getLast() != 0) ...{
    将该用户加入黑名单
    //IP ip = new IP();
    //ip.setIP(request.getRemoteAddr());
    得到当前时间
    //Calendar cal = Calendar.getInstance();
    //SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //String time=formatter.format(cal.getTime());
    //ip.setComments("刷新太快,IP已经被封锁");
    //try ...{
    //ip.insertIP();
    //res.sendRedirect("err.jsp?errmsg=refresh");
    //return;
    //}catch(Exception e) ...{
    //e.printStackTrace();
    //}finally...{
    //ip.closeConn();}
    //}
    //} else ...{
    当前访问者为初次访问
    //ArrayTime timeQueue = new ArrayTime();
    //timeQueue.setLength(maxCount);
    //timeQueue.init();
    //vis=new Visitor();
    //vis.setSessionID(sessionID);
    //vis.setRequestTimeQueue(timeQueue);
    //vis.getRequestTimeQueue().insert(now.getTime());
    //visitors.put(sessionID,vis);
    //}


}

3..>>>>>>>>>>>>>>>>>>>>>>>>>>单元测试>>>>>>>>>>>>>>>>>>>>>>

 [TestMethod]
        public void DemoTest()
        {
            string html = string.Empty;
            string postUrl = "http://localhost:8088/api/Demo/Test";
            string paramData = "userId=jlk456j5";//体参数
            Encoding dataEncode = Encoding.UTF8;
            try
            {
                byte[] byteArray = dataEncode.GetBytes(paramData); //转化
                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
                webReq.ContentLength = byteArray.Length;

                webReq.Headers["userId"] = "myid"; //头参数
                webReq.Headers["userPwd"] = "mypwd";

                Stream newStream = webReq.GetRequestStream();
                newStream.Write(byteArray, 0, byteArray.Length);//写入参数
                newStream.Close();
                HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();

                2
                //StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                //ret = sr.ReadToEnd();
                //sr.Close();
                //response.Close();
                //newStream.Close();

                using (var s = response.GetResponseStream())
                {
                    //Encoding encode = Encoding.GetEncoding("gb2312");
                    Encoding encode = Encoding.GetEncoding("utf-8");
                    Byte[] read = new Byte[512];
                    int bytes = s.Read(read, 0, 512);
                    while (bytes > 0)
                    {
                        html += encode.GetString(read, 0, bytes);
                        bytes = s.Read(read, 0, 512);
                    }
                }

                response.Close();
                newStream.Close();
            }
            catch (Exception ex)
            {
                string tt = "";
            }

            string result = html;
        }









你可能感兴趣的:(ApiController的过滤器使用)