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); }