【问题标题】:Where should static files middleware be in the ASP.NET Core pipeline?静态文件中间件应该在 ASP.NET Core 管道中的什么位置?
【发布时间】:2018-07-06 10:12:25
【问题描述】:

我正在使用 ASP.NET Core 2.1。我认为静态文件中间件应该在 mvc 中间件之前 - 例如,不需要通过 mvc 运行请求来提供 css 文件。

所以我按以下顺序排列:

app.UseExceptionHandler(/*...*/)
app.UseHsts();
app.UseHttpsRedirection();
app.UseStatusCodePagesWithReExecute(/*...*/);
// and lastly:
app.UseStaticFiles();
app.UseMvc(/*...*/);

但是,当我打开调试级别日志记录时,我注意到如果缺少静态文件,它会运行 Microsoft.AspNetCore.Builder.RouterMiddleware 并显示 Request did not match any routes,然后运行我的 ErrorController 并针对该请求发出 404。

所以:

  • 这是管道的正确顺序吗?
  • 有没有办法避免这一切,还是有意为之?例如一些“更轻松”的过程来触发 404 而无需经历所有这些?就像可能首先使用静态文件中间件(但不确定这是否明智/安全)?

【问题讨论】:

  • 您有没有机会在这里查看官方文档docs.microsoft.com/en-us/aspnet/core/fundamentals/… ?它应该为您的担忧增加一些洞察力。
  • @Nkosi 谢谢,是的,我读到了
  • 你有没有试过改变顺序看看会发生什么?
  • @Brad 我想专业地处理这个问题,而不是反复试验。我已经在我的回答中暗示,管道在这么多教程中显示的事实可能是(我猜),因为它是最安全的。我不确定在安全中间件之前放置东西会产生什么后果。获得安全权利很难,所以我在这里向有相关经验的人学习。

标签: c# asp.net-core asp.net-core-2.1


【解决方案1】:

这是管道的正确顺序吗?

是的。

但是,当我打开调试级别日志记录时,我注意到如果缺少静态文件,它会运行 Microsoft.AspNetCore.Builder.RouterMiddleware 并显示 Request did not match any routes,然后运行我的 ErrorController 并针对该请求发出 404。为什么?

首先,您丢失的静态文件请求正在通过异常处理程序、HSTS、HTTPS 重定向和 StatusCodePagesWithReExecute 中间件,但让我们忽略它们,因为没有什么有趣的。请求只是通过它们。

然后,由静态文件中间件处理。中间件很快就会明白,该文件丢失了,只是让您的请求运行到下一个中​​间件,即 MVC 中间件。

MVC 中间件查看其路由表并找到“catchAll”路由并让ErrorController 处理请求。这就是ErrorController处理丢失文件的原因。

附:我想你有这样的“catchAll”路线:

app.UseMvc(routes =>
        {
            .... // your routes here

            routes.MapRoute("catchAll", "{*.}", new { controller = "Error", action = "Error404" }
        });

【讨论】:

  • 那么您将如何设置您的管道?你不会把静态文件放在第一位吗?
  • 不,静态文件中间件在逻辑上就在它的位置上。我的意思是您可以根据需要重新排列中间件。但是如果静态中间件是管道中的第一个并且其中发生异常,您的应用程序将不知道异常,因为app.UseExceptionHandler 中间件将没有能力处理异常。 app.UseHttpsRedirection 中间件也是如此:我们希望我们的应用程序只处理安全请求(甚至是静态文件),因此首先检查请求是否使用 https 模式然后让静态文件中间件运行是有意义的。
  • 是的,这是有道理的。我想要静态文件中间件之前的安全性。
【解决方案2】:

为了让它更轻,你可以有一个像这样的自定义中间件:

var avoidFolders = new string[] { "js", "css" };

app.Use(async (context, next) => {
    if (avoidFolders.Contains(context.Request.Path.Value.Trim('/')))
        context.Response.StatusCode = 404;
    else await next();
});

虽然您必须在数组中包含每个静态文件夹,但它确保直接返回 404 而无需继续进行路由。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 2010-12-14
    • 2019-07-23
    相关资源
    最近更新 更多