f4388a5cc3
Any /cms/* hit (including exact /cms) that fails authorization returns 404 instead of redirecting to /account/login. CMS-PLAN §3.4 constraint.
35 lines
1.3 KiB
C#
35 lines
1.3 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Authorization.Policy;
|
|
|
|
namespace DeepDrftWeb.Middleware;
|
|
|
|
/// <summary>
|
|
/// Returns 404 for any /cms/* request that fails authorization.
|
|
/// This prevents the CMS from acknowledging its own existence to unauthorized callers
|
|
/// (a redirect to /account/login would reveal that the route exists).
|
|
/// CMS-PLAN §3.4 stealth-routing constraint.
|
|
/// </summary>
|
|
public class CmsStealthRoutingHandler : IAuthorizationMiddlewareResultHandler
|
|
{
|
|
private readonly AuthorizationMiddlewareResultHandler _default = new();
|
|
|
|
public async Task HandleAsync(
|
|
RequestDelegate next,
|
|
HttpContext context,
|
|
AuthorizationPolicy policy,
|
|
PolicyAuthorizationResult authorizeResult)
|
|
{
|
|
// For /cms/* routes (including an exact /cms hit), map any authorization
|
|
// failure to 404 regardless of cause (unauthenticated, wrong role, or any
|
|
// future policy failure). This prevents the CMS from acknowledging its
|
|
// own existence to callers outside the Admin hierarchy.
|
|
if (context.Request.Path.StartsWithSegments("/cms") && !authorizeResult.Succeeded)
|
|
{
|
|
context.Response.StatusCode = StatusCodes.Status404NotFound;
|
|
return;
|
|
}
|
|
|
|
await _default.HandleAsync(next, context, policy, authorizeResult);
|
|
}
|
|
}
|