示例#1
0
        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var cacheProvider  = context.HttpContext.RequestServices.GetService <IDistributedCache>();
            var captchaOptions = context.HttpContext.RequestServices.GetService <IOptions <CaptchaOptions> >()?.Value ??
                                 new CaptchaOptions();
            var descriptor = context?.ActionDescriptor as ControllerActionDescriptor;

            if (!captchaOptions.IsCaptchaEnabled)
            {
                return;
            }

            string actionName     = descriptor.ActionName;
            string controllerName = descriptor.ControllerName;

            if (captchaOptions.IsEnabledThreshold)
            {
                string thresholdKeyName = $"{controllerName}_{actionName}_{CaptchaType.ToString()}_Threshold";

                if (Threshold == -1)
                {
                    Threshold = captchaOptions.Threshold;
                }
            }

            if (captchaOptions.IsEnabledDuration)
            {
                string durationKeyName = $"{controllerName}_{actionName}_{CaptchaType.ToString()}_Duration";

                if (Duration == -1)
                {
                    Duration = captchaOptions.Duration;
                }
            }

            string cacheKeyPattern =
                context.GetCacheKey(captchaOptions.DomainName, CaptchaType, FieldName, GlobalCacheName);

            int cacheVisitedCount = cacheProvider.Get <int>(cacheKeyPattern);

            if (cacheVisitedCount >= Threshold)
            {
                var tokenHeader = context.HttpContext?.Request?.Headers?.TryGetValue(
                    captchaOptions.CaptchaTokenHeaderName,
                    out StringValues token);
                if (tokenHeader.HasValue && !string.IsNullOrEmpty(token))
                {
                    await CheckCaptchaTokenAsync(context, cacheProvider, cacheKeyPattern, cacheVisitedCount, captchaOptions, token.ToString());
                }
                else
                {
                    AddToCache(cacheProvider, cacheKeyPattern, cacheVisitedCount);
                    context.Result = new ContentResult()
                    {
                        Content    = "Too Many Requests",
                        StatusCode = (int)HttpStatusCode.TooManyRequests
                    };
                }
            }
            else
            {
                AddToCache(cacheProvider, cacheKeyPattern, cacheVisitedCount);
            }

            await base.OnActionExecutionAsync(context, next);
        }