Exclude Rate Limiting for SignalR and WebSockets In BlazorServer
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [x] 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()
.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 =>
{
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_
Contributor guide
Assessment
This issue has not been assessed yet.