Пример #1
0
        public async Task <LimitRequestBannedData> CheckForBanAndIncreaseRequestsCount(
            string ip,
            int requestsPerTime,
            TimeSpan time,
            TimeSpan banTime,
            string controllerName,
            string actionName,
            string methodType,
            bool uniqueForEveryActionAndController = true,
            bool useTestMode = false)
        {
            if (useTestMode)
            {
                ip = $"101.TEST.MODE.101";
            }
            if (uniqueForEveryActionAndController)
            {
                ip = GenerateUniquePathKeyIp(methodType, ip, controllerName, actionName);
            }
            else
            {
                ip = "LimitRequestsCounter:" + ip;
            }

            await UpdateValidToTime(ip, time);

            LimitRequestBannedData isBannedData = await IsBannedAsync(ip);

            bool isBanned = isBannedData.IsBanned;

            if (isBanned)
            {
                return(isBannedData);
            }
            else
            {
                await SetIpRequestsCountAsync(ip, time);

                if (await GetIpRequestCountAsync(ip) >= requestsPerTime)
                {
                    await BanIpRequestsAsync(ip.ToString(), banTime);
                }
                return(isBannedData);
            }
        }
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var limitRequestsService = context.HttpContext.RequestServices.GetRequiredService <ILimitRequestsService>();
            var ip = context.HttpContext.Connection.RemoteIpAddress?.ToString();

            if (ip == null && useTestMode == false)
            {
                //TODO: Think what to do if we don't have the IP in the request.
                await next();

                return;
            }
            string controllerName = context.RouteData.Values["controller"].ToString();
            string actionName     = context.RouteData.Values["action"].ToString();
            string methodType     = context.HttpContext.Request.Method;

            LimitRequestBannedData data = await limitRequestsService.CheckForBanAndIncreaseRequestsCount(ip, requestsPerTime, time, banTime, controllerName, actionName, methodType, uniqueForEveryActionAndController, useTestMode);

            if (data.IsBanned)
            {
                var options = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };
                if (data.ExpiryDate?.CompareTo(TimeSpan.FromSeconds(1)) == -1)
                {
                    data.ExpiryDate = TimeSpan.FromSeconds(1);
                }
                string tryAgainAfter = data.ExpiryDate?.ToString(@"dd\.hh\:mm\:ss");
                var    contentResult = new ContentResult
                {
                    Content = JsonSerializer.Serialize(
                        new ApiResponse(400, $"You have made too many requests!Try again after {tryAgainAfter}"), options),
                    ContentType = "application/json",
                    StatusCode  = 400
                };

                context.Result = contentResult;
                return;
            }
            //move to controller
            await next();
        }
Пример #3
0
        public async Task <LimitRequestBannedData> IsBannedAsync(string ip)
        {
            if (database.KeyExists(ip + ":banned"))
            {
                RedisValueWithExpiry data = await database.StringGetWithExpiryAsync(ip + ":banned");

                LimitRequestBannedData returnData = new LimitRequestBannedData()
                {
                    IsBanned   = true,
                    ExpiryDate = data.Expiry
                };
                return(returnData);
            }
            return(new LimitRequestBannedData()
            {
                IsBanned = false
            });


            //return await database.KeyExistsAsync(ip + ":banned");
        }