fix: Rate-Limit hinter Reverse Proxy wirkte wie ein globales statt Pro-IP-Limit
RemoteIpAddress zeigte hinter Dokploy/Traefik ohne ForwardedHeaders-Middleware für jede Anfrage auf dieselbe interne Proxy-IP - das Pro-IP-Limit (120/Minute) wurde dadurch faktisch zu einem einzigen globalen Limit für die gesamte Bereitstellung, geteilt von allen Geräten und Endpunkten zusammen. ForwardedHeadersOptions (X-Forwarded-For/X-Forwarded-Proto) registriert, KnownIPNetworks/KnownProxies geleert (Container nur über den Reverse Proxy erreichbar). API-only-Fix, Server-Redeploy nötig. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ using System.Text;
|
||||
using System.Threading.RateLimiting;
|
||||
using LehrerApp.Api;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
@@ -36,6 +37,19 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
});
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
// Läuft hinter einem Reverse Proxy (Dokploy/Traefik) - ohne diese Weiterleitung sähe Kestrel für
|
||||
// JEDE Anfrage dieselbe interne Proxy-IP als Connection.RemoteIpAddress, wodurch das unten
|
||||
// definierte Pro-IP-Rate-Limit faktisch zu einem einzigen globalen Limit für die gesamte
|
||||
// Bereitstellung würde (Bug, siehe TODO.md 10.2.2 Nachtrag). KnownNetworks/KnownProxies bewusst
|
||||
// geleert: der Container ist nur über den Reverse Proxy erreichbar, nie direkt aus dem Internet,
|
||||
// daher ist der unmittelbare Absender von X-Forwarded-For hier immer vertrauenswürdig.
|
||||
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
options.KnownIPNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
});
|
||||
|
||||
// Rate Limiting (10.2.2): striktes Limit gezielt gegen Brute-Force auf /api/auth/login, plus ein
|
||||
// grobes globales Limit pro IP als einfacher Schutz vor Überlastung der übrigen Endpunkte.
|
||||
builder.Services.AddRateLimiter(options =>
|
||||
@@ -69,6 +83,7 @@ builder.Services.AddSingleton<PlainEventStore>(sp =>
|
||||
new PlainEventStore(sp.GetRequiredService<EventStore>()));
|
||||
|
||||
var app = builder.Build();
|
||||
app.UseForwardedHeaders();
|
||||
app.UseRateLimiter();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
Reference in New Issue
Block a user