Giter Club home page Giter Club logo

Comments (20)

stefanprodan avatar stefanprodan commented on May 8, 2024

Well you white listed that client key... remove it from ClientWhitelist.

Also copy this code in Startup.ConfigureServices. In your code I see that you didn't inject MemoryCacheClientPolicyStore and MemoryCacheRateLimitCounterStore as singleton.

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Also that GeneralRules and ClientRateLimiting are incorrect.

First of all you should set EnableEndpointRateLimiting as true if you want to target specific paths.

All your path are invalid at this point because you didn't follow the endpoint convention.

Instead of "Endpoint": "" should be "Endpoint": "*",

Instead of "Endpoint": "/entity/yyy" should be "Endpoint": "*:/entity/yyy"

Please take a look at the Defining rate limit rules documentation.

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Also you white listed the endpoint get:/entity/yyy remove it

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Can you help me to understand about GeneralRules / ClientRules which are mandatory for ClientRateLimit

The reason why i am asking this question is, when i tested. it always considering the GeneralRules. So I am not sure where the settings are wrong. Based on my assumption it should allow ":/entity/xxx" for 3 times and ":/entity/yyy" for 4 times but it always taking 2 times which is in the General rules.

"API calls quota exceeded! maximum admitted 2 per 15m."

"ClientRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"EndpointWhitelist": [ ],
"ClientWhitelist": [ ],
"GeneralRules": [
{
"Endpoint": "",
"Period": "1s",
"Limit": 2
},
{
"Endpoint": "
",
"Period": "15m",
"Limit": 2
},
{
"Endpoint": "",
"Period": "12h",
"Limit": 4
},
{
"Endpoint": "
",
"Period": "7d",
"Limit": 10
}
]
},
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "cMGAysfu_LfJ7HU8lYFlWtTyWMj85WdbmPShMWbBSgw",
"Rules": [
{
"Endpoint": ":/entity/xxx",
"Period": "1s",
"Limit": 1
},
{
"Endpoint": "
:/entity/xxx",
"Period": "15m",
"Limit": 3
},
{
"Endpoint": ":/entity/yyy",
"Period": "1s",
"Limit": 1
},
{
"Endpoint": "
:/entity/yyy",
"Period": "15m",
"Limit": 4
}
]
}
]
}

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

The GeneralRules are applied for all client IDs, you can override these rules for specific clients using the ClientRules.

If you define general rules as in:

"GeneralRules": [
      {
        "Endpoint": "*",
        "Period": "1s",
        "Limit": 2
      },
      {
        "Endpoint": "*",
        "Period": "15m",
        "Limit": 100
      }
    ]

And client rules as in:

    "ClientRules": [
      {
        "ClientId": "client-id-1",
        "Rules": [
          {
            "Endpoint": "*",
            "Period": "1s",
            "Limit": 10
          },
          {
            "Endpoint": "*",
            "Period": "15m",
            "Limit": 200
          }
        ]
      }
    ]

Then a client with ID client-id-1 will have a rate limit of 10/sec, but a client with ID client-id-2 with have a rate limit of 2/sec since client-id-2 is not in the ClientRules.

If you want to set the same rate limits for all your clients then don't fill the ClientRules and use only GeneralRules.

All this is explained in the docs

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Also in your config the endpoints are wrong...

"Endpoint": ":/entity/xxx", is not valid, use "Endpoint": "*:/entity/xxx",

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Also your GeneralRules are wrong...

"Endpoint": "", is not valid, use "Endpoint": "*",

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

I dont know the reason, why its showing like that but actually i configured correctly

"ClientRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"EndpointWhitelist": [ ],
"ClientWhitelist": [ ],
"GeneralRules": [
{
"Endpoint": "",
"Period": "1s",
"Limit": 2
},
{
"Endpoint": "
",
"Period": "15m",
"Limit": 2
},
{
"Endpoint": "",
"Period": "12h",
"Limit": 4
},
{
"Endpoint": "
",
"Period": "7d",
"Limit": 10
}
]
},
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "cMGAysfu_LfJ7HU8lYFlWtTyWMj85WdbmPShMWbBSgw",
"Rules": [
{
"Endpoint": ":/entity/xxx",
"Period": "1s",
"Limit": 1
},
{
"Endpoint": "
:/entity/xxx",
"Period": "15m",
"Limit": 3
},
{
"Endpoint": ":/entity/yyy",
"Period": "1s",
"Limit": 1
},
{
"Endpoint": "
:/entity/yyy",
"Period": "15m",
"Limit": 4
},
{
"Endpoint": ":/zzz",
"Period": "1s",
"Limit": 1
},
{
"Endpoint": "
:/zzz",
"Period": "15m",
"Limit": 5
}
]
}
]
}

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

ah ok, when you post code on github you have to use markdown code blocks, take a look here https://help.github.com/articles/creating-and-highlighting-code-blocks/

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Use the code blocks to post your code and I will test your setup

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Thanks stefan. Please find the configurations below.

 // needed to load configuration from appsettings.json
            services.AddOptions();
            // needed to store rate limit counters and ip rules
            services.AddMemoryCache();
            //load general configuration from appsettings.json
            services.Configure<ClientRateLimitOptions>(Configuration.GetSection("ClientRateLimiting"));
            //load client rules from appsettings.json
            services.Configure<ClientRateLimitPolicies>(Configuration.GetSection("ClientRateLimitPolicies"));
            // inject counter and rules stores
            services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
            services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
            // inject counter and rules distributed cache stores
            services.AddSingleton<IClientPolicyStore, DistributedCacheClientPolicyStore>();
            services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
            var opt = new ClientRateLimitOptions();
            ConfigurationBinder.Bind(Configuration.GetSection("ClientRateLimiting"), opt);

app.UseClientRateLimiting();


"ClientRateLimiting": {
    "EnableEndpointRateLimiting": true,
    "StackBlockedRequests": false,
    "ClientIdHeader": "X-ClientId",
    "HttpStatusCode": 429,
    "EndpointWhitelist": [ ],
    "ClientWhitelist": [ ],
    "GeneralRules": [
      {
        "Endpoint": "*",
        "Period": "1s",
        "Limit": 2
      },
      {
        "Endpoint": "*",
        "Period": "15m",
        "Limit": 2
      },
      {
        "Endpoint": "*",
        "Period": "12h",
        "Limit": 4
      },
      {
        "Endpoint": "*",
        "Period": "7d",
        "Limit": 10
      }
    ]
  },
  "ClientRateLimitPolicies": {
    "ClientRules": [
      {
        "ClientId": "cMGAysfu_LfJ7HU8lYFlWtTyWMj85WdbmPShMWbBSgw",
        "Rules": [
          {
            "Endpoint": "*:/entity/xxx",
            "Period": "1s",
            "Limit": 1
          },
          {
            "Endpoint": "*:/entity/xxx",
            "Period": "15m",
            "Limit": 3
          },
          {
            "Endpoint": "*:/entity/yyy",
            "Period": "1s",
            "Limit": 1
          },
          {
            "Endpoint": "*:/entity/yyy",
            "Period": "15m",
            "Limit": 4
          },
          {
            "Endpoint": "*:/zzz",
            "Period": "1s",
            "Limit": 1
          },
          {
            "Endpoint": "*:/zzz",
            "Period": "15m",
            "Limit": 5
          }
        ]
      }
    ]
  }

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Ok I've run your setup and I get:

API calls quota exceeded! maximum admitted 3 per 15m.

Maybe the client rule doesn't apply because you didn't set the HTTP header:

X-ClientId: cMGAysfu_LfJ7HU8lYFlWtTyWMj85WdbmPShMWbBSgw

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Ok thanks for the information. However we have used OAuth token concept so when request come client send the token only so is there a way to validate this x-ClientId from the user identity?

from aspnetcoreratelimit.

sANDwORm avatar sANDwORm commented on May 8, 2024

Here is how we solved it:

    public class AppClientRateLimitMiddleware : ClientRateLimitMiddleware
    {
        private readonly IOptions<ClientRateLimitOptions> _options;

        public AppClientRateLimitMiddleware(RequestDelegate next, IOptions<ClientRateLimitOptions> options, IRateLimitCounterStore counterStore, IClientPolicyStore policyStore, ILogger<ClientRateLimitMiddleware> logger) 
            : base(next, options, counterStore, policyStore, logger)
        {
            _options = options;
        }

        public override ClientRequestIdentity SetIdentity(HttpContext httpContext)
        {
            var clientRequestIdentity = base.SetIdentity(httpContext);

            var userId = ClientIdHelper.GetClientIdFromContext(httpContext, _options.Value.ClientIdHeader);
            if (userId != null)
            {
                clientRequestIdentity.ClientId = userId;
            }
            return clientRequestIdentity;
        }
    }

    public class ClientIdHelper
    {
        public static string GetClientIdFromContext(HttpContext httpContext, string clientIdClaimType)
        {
            string userId = null;
            if (httpContext.User.Identity.IsAuthenticated)
            {
                var identity = httpContext.User.Identity as ClaimsIdentity;
                userId = identity?.Claims?.SingleOrDefault(c => c.Type == clientIdClaimType)?.Value;
            }
            return userId;
        }
    }

Then we missused appsetting.json and set "ClientIdHeader": "uid" where "uid" is our user id (client id) in token claim. In you case it could be something else.

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

Thanks @sANDwORm I should put this in the docs. Is the uid header a standard approach with OAuth2 ?

from aspnetcoreratelimit.

sANDwORm avatar sANDwORm commented on May 8, 2024

We are using our custom JWT tokens. If client has meaning of end user (not client application) and limitation is to be set against it, JWT OAuth access token contain"sub" claim type.

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Thanks sANDwORm and stefan for all your support.

Its working for me.

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Hi Stefan,

We have a requirement to limit the number of records returnd for a specific time frame. So can use this library to configure that.

from aspnetcoreratelimit.

stefanprodan avatar stefanprodan commented on May 8, 2024

@radduri HTTP request rate limiting is not related to your requirement. Rate limiting records should be implemented in the repository layer and/or caching layer. If your company needs consultancy you can contact me on my work mail stefan.prodan(at)veritech.io

from aspnetcoreratelimit.

radduri avatar radduri commented on May 8, 2024

Sure. Thanks for the information.

from aspnetcoreratelimit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.