Skip to content

Exclude Rate Limiting for SignalR and WebSockets In BlazorServer #61973

Open
@HakamFostok

Description

@HakamFostok

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

I want to implement RateLimiting on BlazorWebServer, I am doing that according to the documentation

https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-9.0#apply-rate-limiting-to-server-side-blazor-apps

services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = (int)HttpStatusCode.TooManyRequests;
    options.AddTokenBucketLimiter("pages", opt =>
    {
        opt.TokenLimit = 10;
        opt.TokensPerPeriod = 10;
        opt.ReplenishmentPeriod = TimeSpan.FromSeconds(5);
        opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    });
});


  app.UseRateLimiter(); 
  app.MapRazorComponents<App>()
     .AddInteractiveServerRenderMode()
     .RequireRateLimiting("pages");

I sometimes get error 329 in the browser console when SignalR and web sockets establish the connection.
Those technologies are chatty, if I am not mistaken.
here is an example of the errors I am receiving

WebSocket connection to 'ws://localhost:5000/_blazor?id=N4noD6idr-OZDfLxIUIgXg' failed: Error during WebSocket handshake: Unexpected response code: 429
	http://localhost:5000/_framework/blazor.web.js:0:0
Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.
	http://localhost:5000/_framework/blazor.web.js:0:47018
Failed to load resource: the server responded with a status of 429 (Too Many Requests)		http://localhost:5000/_blazor/negotiate?negotiateVersion=1:0:0
Failed to complete negotiation with the server: Error: Too Many Requests: Status code '429'	http://localhost:5000/_framework/blazor.web.js:0:47018
Failed to start the connection: Error: Failed to complete negotiation with the server: Error: Too Many Requests: Status code '429'	http://localhost:5000/_framework/blazor.web.js:0:47018
Failed to complete negotiation with the server: Error: Too Many Requests: Status code '429'	http://localhost:5000/_framework/blazor.web.js:0:39472

I think everyone needs rate limiting only for the browsing of the pages, I do not need the user to refresh the page 5 times in one second, for example.

But when I come to SignalR and WebSocket, I do not want to interfere with them, if they are chatty, then this is how they are designed.

I have consulted GPT and it suggests the following

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = (int)HttpStatusCode.TooManyRequests;

    options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
    {
        var path = httpContext.Request.Path;

        // Bypass SignalR/WebSocket paths
        if (path.StartsWithSegments("/_blazor") || path.StartsWithSegments("/chathub"))
        {
            return RateLimitPartition.GetNoLimiter("SignalR");
        }

        return RateLimitPartition.GetTokenBucketLimiter("pages", _ => new TokenBucketRateLimiterOptions
        {
            TokenLimit = 10,
            TokensPerPeriod = 10,
            ReplenishmentPeriod = TimeSpan.FromSeconds(5),
            QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
        });
    });
});

but I am not sure if this is good enough or not?

Describe the solution you'd like

I am suggesting either

  1. Updating the documentation to explain how to exclude SignalR and WebSockets from the Rate Limiting
  2. Excluding the SignalR and WebSockets from rate limiting automatically and applying the policy only on page requests

Thank you

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewaresfeature-rate-limitWork related to use of rate limit primitives

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions