fix #6166 - move UseAntiforgery after UseNotFoundResponse and adjust 404 handling logic

This commit is contained in:
sbwalker
2026-04-08 16:40:06 -04:00
parent 1741029057
commit 0ea27e7147

View File

@@ -67,8 +67,8 @@ namespace Oqtane.Extensions
app.UseOutputCache(); app.UseOutputCache();
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.UseAntiforgery();
app.UseNotFoundResponse(); app.UseNotFoundResponse();
app.UseAntiforgery();
// execute any IServerStartup logic // execute any IServerStartup logic
app.ConfigureOqtaneAssemblies(environment); app.ConfigureOqtaneAssemblies(environment);
@@ -153,28 +153,33 @@ namespace Oqtane.Extensions
public static IApplicationBuilder UseNotFoundResponse(this IApplicationBuilder app) public static IApplicationBuilder UseNotFoundResponse(this IApplicationBuilder app)
{ {
// set the route to be rendered on NavigationManager.NotFound()
const string notFoundRoute = "/404"; const string notFoundRoute = "/404";
app.UseStatusCodePagesWithReExecute(notFoundRoute, createScopeForStatusCodePages: true); app.UseStatusCodePagesWithReExecute(notFoundRoute, createScopeForStatusCodePages: true);
// middleware to determine if status code pages should be skipped
app.Use(async (context, next) => app.Use(async (context, next) =>
{ {
var path = context.Request.Path.Value ?? string.Empty; var path = context.Request.Path.Value ?? string.Empty;
if (string.IsNullOrEmpty(path) || ShouldSkipStatusCodeReExecution(path)) if (ShouldSkipStatusCodeReExecution(path))
{ {
var feature = context.Features.Get<IStatusCodePagesFeature>(); var statusCodePagesFeature = context.Features.Get<IStatusCodePagesFeature>();
feature?.Enabled = false; if (statusCodePagesFeature != null)
{
statusCodePagesFeature.Enabled = false;
}
} }
await next(); await next();
}); });
// middleware to rewrite the path for 404 status code responses on sites using subfolders
app.Use(async (context, next) => app.Use(async (context, next) =>
{ {
var feature = context.Features.Get<IStatusCodeReExecuteFeature>(); var statusCodeReExecuteFeature = context.Features.Get<IStatusCodeReExecuteFeature>();
var handled = false; if (statusCodeReExecuteFeature != null
if (feature != null
&& context.Response.StatusCode == (int)HttpStatusCode.NotFound && context.Response.StatusCode == (int)HttpStatusCode.NotFound
&& notFoundRoute.Equals(context.Request.Path.Value, StringComparison.OrdinalIgnoreCase)) && string.Equals(context.Request.Path.Value, notFoundRoute, StringComparison.OrdinalIgnoreCase))
{ {
var alias = context.GetAlias(); var alias = context.GetAlias();
if (!string.IsNullOrEmpty(alias?.Path)) if (!string.IsNullOrEmpty(alias?.Path))
@@ -183,20 +188,17 @@ namespace Oqtane.Extensions
context.Request.Path = new PathString($"/{alias.Path}{notFoundRoute}"); context.Request.Path = new PathString($"/{alias.Path}{notFoundRoute}");
try try
{ {
handled = true;
await next(); await next();
} }
finally finally
{ {
context.Request.Path = originalPath; context.Request.Path = originalPath;
} }
return;
} }
} }
if (!handled)
{
await next(); await next();
}
}); });
return app; return app;
@@ -204,12 +206,16 @@ namespace Oqtane.Extensions
static bool ShouldSkipStatusCodeReExecution(string path) static bool ShouldSkipStatusCodeReExecution(string path)
{ {
return Constants.ReservedRoutes.Any(item => path.Contains("/" + item + "/")) || HasStaticFileExtension(path); // skip requests for framework resources, reserved routes, and static files
return path.StartsWith("/_framework/", StringComparison.OrdinalIgnoreCase) ||
path.StartsWith("/_content/", StringComparison.OrdinalIgnoreCase) ||
Constants.ReservedRoutes.Any(item => path.Contains("/" + item + "/")) ||
HasStaticFileExtension(path);
} }
static bool HasStaticFileExtension(string path) static bool HasStaticFileExtension(string path)
{ {
return !string.IsNullOrEmpty(Path.GetExtension(path)); return !string.IsNullOrEmpty(Path.GetExtension(path)) && Path.GetExtension(path).Length != 1;
} }
} }
} }