コード例 #1
0
        public async Task <IViewComponentResult> InvokeAsync(string id)
        {
            string clientId = id;

            if (string.IsNullOrWhiteSpace(clientId))
            {
                var clients = await _clientStore.GetAllClientIdsAsync();

                clientId = clients.FirstOrDefault();
            }
            var client = await _clientStore.FindClientByIdAsync(clientId);

            var clientRequestIdentity = new ClientRequestIdentity()
            {
                ClientId = clientId
            };

            var rateLimitClientsRule = _processor.GetRateLimitClientsRule(clientRequestIdentity);
            List <RateLimitRuleRecord> rateLimitRuleRecords = new List <RateLimitRuleRecord>();

            if (rateLimitClientsRule != null)
            {
                foreach (var rateLimitRule in rateLimitClientsRule.Settings.RateLimitRules)
                {
                    var rateLimitCounter = _processor.GetStoredRateLimitCounter(clientRequestIdentity, rateLimitRule);
                    rateLimitRuleRecords.Add(new RateLimitRuleRecord()
                    {
                        RateLimitCounter = rateLimitCounter,
                        RateLimitRule    = rateLimitRule
                    });
                }
            }

            var usageRecords = await _clientUsageStore.GetClientUsageRecordsAsync(clientId, null, (null, null));

            var model = new ClientViewComponentModel
            {
                ClientExtra          = client as ClientExtra,
                RateLimitRuleRecords = rateLimitRuleRecords,
                UsageRecords         = usageRecords == null?null:usageRecords.ToList()
            };

            return(View(model));
        }
        async Task <IRequestTrackerResult> PreEvaluateRateLimitRules(IdentityServerRequestRecord requestRecord)
        {
            // ONLY CHECK THE COUNT and Deny.  DO NOT MUTATE any data
            var identity = new ClientRequestIdentity()
            {
                ClientId    = requestRecord.Client.ClientId,
                EndpointKey = requestRecord.EndpointKey
            };
            var rateLimitClientsRule = _processor.GetRateLimitClientsRule(identity);

            if (rateLimitClientsRule == null)
            {
                // no rules for us to evaluate
                return(null);
            }

            var result = _serviceProvider.GetService <ClientRateLimiterRequestTrackerResult>();

            result.RateLimitClientsRule        = rateLimitClientsRule;
            result.IdentityServerRequestRecord = requestRecord;
            result.Directive = RequestTrackerEvaluatorDirective.AllowRequest;
            foreach (var rule in rateLimitClientsRule.Settings.RateLimitRules)
            {
                if (rule.Limit > 0)
                {
                    // get the current counter
                    var counter = _processor.GetCurrentRateLimitCounter(identity, rule);
                    // check if key expired
                    if (counter.Timestamp + rule.PeriodTimespan.Value < DateTime.UtcNow)
                    {
                        continue;
                    } // check if limit is reached

                    if (counter.TotalRequests >= rule.Limit)
                    {
                        //compute retry after value
                        var retryAfter = _processor.RetryAfterFrom(counter.Timestamp, rule);

                        // log blocked request
                        LogBlockedRequest(requestRecord.HttpContext, identity, counter, rule);

                        // break execution

                        result.Directive  = RequestTrackerEvaluatorDirective.DenyRequest;
                        result.Rule       = rule;
                        result.RetryAfter = retryAfter;

                        return(result);
                    }
                }
                else
                {
                    // process request count
                    var counter = _processor.GetCurrentRateLimitCounter(identity, rule);

                    // log blocked request
                    LogBlockedRequest(requestRecord.HttpContext, identity, counter, rule);

                    // break execution (Int32 max used to represent infinity)
                    // break execution

                    result.Directive  = RequestTrackerEvaluatorDirective.DenyRequest;
                    result.Rule       = rule;
                    result.RetryAfter = Int32.MaxValue.ToString(System.Globalization.CultureInfo.InvariantCulture);

                    return(result);
                }
            }

            result.Rule = rateLimitClientsRule.Settings.RateLimitRules
                          .OrderByDescending(x => x.PeriodTimespan.Value).First();

            return(result);
        }