예제 #1
0
        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));
        }
예제 #2
0
        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"));
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        // 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
            });
        }