public static void ConfigureRateLimiting(HttpFilterCollection filters) { var rateLimitingPolicyParametersProvider = new SampleRateLimitingClientPolicyProvider(); var globalRateLimitingClientPolicyManager = new RateLimitingPolicyManager(rateLimitingPolicyParametersProvider) .AddPathToWhiteList("/api/unlimited") .AddPoliciesForAllEndpoints(new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(100, RateLimitUnit.PerMinute) }, allowAttributeOverride: true, name: "StaticPolicy_2") .AddEndpointPolicy("/api/globallylimited/{id}", "GET", new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(5, RateLimitUnit.PerMinute), new AllowedConsumptionRate(8, RateLimitUnit.PerHour) }, true, "StaticPolicy_0") .AddEndpointPolicy("/api/globallylimited/{id}/sub/{subid}", RateLimitPolicy.AllHttpMethods, new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(2, RateLimitUnit.PerMinute) }, true, "StaticPolicy_1"); #region Setting up the Redis rate limiter var redisRateLimiterSettings = new RedisRateLimiterSettings(); ConfigureRateLimitingSettings(redisRateLimiterSettings); var rateLimitCacheProvider = new SlidingTimeWindowRateLimiter( redisRateLimiterSettings.RateLimitRedisCacheConnectionString, onThrottled: (rateLimitingResult) => { //_logger.LogInformation( // "Request throttled for client {ClientId} and endpoint {Endpoint}", // rateLimitingResult.CacheKey.RequestId, // rateLimitingResult.CacheKey.RouteTemplate); }, circuitBreaker: new DefaultCircuitBreaker(redisRateLimiterSettings.FaultThreshholdPerWindowDuration, redisRateLimiterSettings.FaultWindowDurationInMilliseconds, redisRateLimiterSettings.CircuitOpenIntervalInSecs, onCircuitOpened: () => { //_logger.LogWarning("Rate limiting circuit opened") }, onCircuitClosed: () => { //logger.LogWarning("Rate limiting circuit closed") })); #endregion filters.Add(new RateLimitingFilter(new RateLimiter(rateLimitCacheProvider, globalRateLimitingClientPolicyManager), filters)); }
private static void SetupPolicyManager(RateLimitingPolicyManager policyManager, RateLimitingRequest rateLimtingRequest, IList <string> whiteListedRequestKeys = null, IList <string> whiteListedPaths = null) { var allowedCallRates = new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(5, RateLimitUnit.PerMinute) }; policyManager.AddRequestKeysToWhiteList(whiteListedRequestKeys ?? new List <string>()); policyManager.AddPathsToWhiteList(whiteListedPaths ?? new List <string>()); policyManager.AddEndpointPolicy(new RateLimitPolicy("testclient_01", "/api/values", "GET", allowedCallRates, name: "RequestKey_Route_Method_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("testclient_01", "/api/values/{id}", "*", allowedCallRates, name: "RequestKey_Route_AllMethods_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("testclient_01", "*", "GET", allowedCallRates, name: "RequestKey_AllRoutes_Method_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("testclient_01", "*", "*", allowedCallRates, name: "RequestKey_AllRoutes_AllMethods_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("*", "/api/values", "GET", allowedCallRates, name: "AllRequestKeys_Route_Method_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("*", "/api/values", "*", allowedCallRates, name: "AllRequestKeys_Route_AllMethods_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("*", "*", "GET", allowedCallRates, name: "AllRequestKeys_AllRoutes_Method_MatchingPolicy_FromManager")); policyManager.AddEndpointPolicy(new RateLimitPolicy("*", "*", "*", allowedCallRates, name: "AllRequestKeys_AllRoutes_AllMethods_MatchingPolicy_FromManager")); }
private static async Task ArangeActAndAssert(string routeTemplate, string method, string requestKey, string expectedPolicyNameToApply, IList <AllowedConsumptionRate> allowedCallRates = null, bool allowAttributeOverride = false, bool returnNullPolicy = false, IList <string> whiteListedRequestKeys = null, IList <string> whiteListedPaths = null, bool isWhiteListedPathTest = false) { var rateLimtingRequest = new RateLimitingRequest(routeTemplate, routeTemplate, method, s => new string[] { "s_value" }, null, null); var policyProviderMock = new Mock <IRateLimitingPolicyProvider>(); if (!isWhiteListedPathTest) { policyProviderMock.Setup(provider => provider.GetPolicyAsync(rateLimtingRequest)) .ReturnsAsync(returnNullPolicy ? null : new RateLimitPolicy(requestKey, allowedCallRates, allowAttributeOverride, name: "CustomProviderPolicy")); } var policyManager = new RateLimitingPolicyManager(policyProviderMock.Object); SetupPolicyManager(policyManager, rateLimtingRequest, whiteListedRequestKeys, whiteListedPaths); var policyToApply = await policyManager.GetPolicyAsync(rateLimtingRequest); policyProviderMock.VerifyAll(); if (expectedPolicyNameToApply == null) { Assert.Null(policyToApply); } else { Assert.Equal(expectedPolicyNameToApply, policyToApply.Name); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Adds services required for using options. services.AddOptions(); #region Setting policies explicitly using code var rateLimitingPolicyParametersProvider = new SampleRateLimitingClientPolicyProvider(); var globalRateLimitingClientPolicyManager = new RateLimitingPolicyManager(rateLimitingPolicyParametersProvider) .AddPathToWhiteList("/api/unlimited") .AddPoliciesForAllEndpoints(new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(1000, RateLimitUnit.PerMinute) }, allowAttributeOverride: true, name: "StaticPolicy_2") .AddEndpointPolicy("/api/globallylimited/{id}", "GET", new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(5, RateLimitUnit.PerMinute), new AllowedConsumptionRate(8, RateLimitUnit.PerHour) }, true, "StaticPolicy_0") .AddEndpointPolicy("/api/globallylimited/{id}/sub/{subid}", RateLimitPolicy.AllHttpMethods, new List <AllowedConsumptionRate>() { new AllowedConsumptionRate(2, RateLimitUnit.PerMinute) }, true, "StaticPolicy_1"); #endregion #region Setting Policies Using Configuration Options // var rateLimitingOptions = new RateLimitingOptions(); // Configuration.GetSection(nameof(RateLimitingOptions)).Bind(rateLimitingOptions); // var globalRateLimitingClientPolicyManager = new RateLimitingPolicyManager( // new SampleRateLimitingClientPolicyProvider()) // .AddPoliciesForAllEndpoints(new List<AllowedCallRate>() {new AllowedCallRate(180, RateLimitUnit.PerMinute)},name:"ClientPolicy") // .AddPathsToWhiteList(rateLimitingOptions.RateLimitingWhiteListedPaths) // .AddRequestKeysToWhiteList(rateLimitingOptions.RateLimitingWhiteListedRequestKeys); #endregion #region Setting up the Redis rate limiter var redisRateLimiterSettings = new RedisRateLimiterSettings(); Configuration.GetSection(nameof(RedisRateLimiterSettings)).Bind(redisRateLimiterSettings); var rateLimitCacheProvider = new SlidingTimeWindowRateLimiter( redisRateLimiterSettings.RateLimitRedisCacheConnectionString, (exp) => _logger.LogError("Error in rate limiting", exp), onThrottled: (rateLimitingResult) => { _logger.LogInformation( "Request throttled for client {ClientId} and endpoint {Endpoint}", rateLimitingResult.CacheKey.RequestId, rateLimitingResult.CacheKey.RouteTemplate); }, circuitBreaker: new DefaultCircuitBreaker(redisRateLimiterSettings.FaultThreshholdPerWindowDuration, redisRateLimiterSettings.FaultWindowDurationInMilliseconds, redisRateLimiterSettings.CircuitOpenIntervalInSecs, onCircuitOpened: () => _logger.LogWarning("Rate limiting circuit opened"), onCircuitClosed: () => _logger.LogWarning("Rate limiting circuit closed"))); #endregion // Add framework services services.AddMvc(options => { #region Adding the RateLimitingFilter options.Filters.Add(new RateLimitingFilter( new RateLimiter(rateLimitCacheProvider, globalRateLimitingClientPolicyManager))); #endregion #region Multi level rate limiting - Multiple action filters based on separate Policy Providers providing separate policies //options.Filters.Add(new RateLimitingFilter( // new RateLimiter(rateLimitCacheProvider, new SampleRateLimitingUserPolicyProvider()))); //options.Filters.Add(new RateLimitingFilter( // new RateLimiter(rateLimitCacheProvider, new SampleRateLimitingOrganizationPolicyProvider()))); #endregion }); }