【问题标题】:UseExceptionHandler() middleware in .NET Core MVC prevents response headers setting.NET Core MVC 中的 UseExceptionHandler() 中间件阻止响应标头设置
【发布时间】:2018-07-30 19:12:50
【问题描述】:

Startup.cs:

// ...
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Frame-Options", "DENY");
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    context.Response.Headers.Add("Server", "ololo");

    await next();
});

if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
else { app.UseExceptionHandler("/Home/Error"); }

app.UseStaticFiles();
app.UseAuthentication();
// ...

当一切正常时,我得到以下标题,正如预期的那样:

HTTP/1.1 200 OK
Connection: close
Date: Mon, 30 Jul 2018 18:39:33 GMT
Content-Type: text/html; charset=utf-8
Server: ololo
Transfer-Encoding: chunked
X-Frame-Options: DENY
X-Content-Type-Options: nosniff

所以ServerX-Frame-OptionsX-Content-Type-Options 标头被覆盖。

但如果我的代码中有未处理的异常,那么我会得到这些标头:

HTTP/1.1 500 Internal Server Error
Connection: close
Date: Mon, 30 Jul 2018 18:35:49 GMT
Content-Type: text/html; charset=utf-8
Server: Kestrel
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Expires: -1

所以标题不会被覆盖。

这是为什么呢?是设计使然吗? Exceptions 中间件的工作方式是否不同,因此它不会通过整个管道?

dotnet --info
.NET Command Line Tools (2.1.4)

Product Information:
 Version:            2.1.4
 Commit SHA-1 hash:  5e8add2190

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.5
  Build    : 17373eb129b3b05aa18ece963f8795d65ef8ea54

【问题讨论】:

  • 是的,这是设计使然,需要考虑在内,对于 CORS 等也是如此。

标签: asp.net-core asp.net-core-mvc


【解决方案1】:

在任何情况下设置标头的更可靠方法是使用OnStarting 回调。见docs

在将响应标头发送到客户端之前添加要调用的委托。

public async Task Invoke(HttpContext context)
{
    context.Response.OnStarting(() =>
    {
        context.Response.Headers.Add("X-Frame-Options", "DENY");
        context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
        context.Response.Headers.Add("Server", "ololo");

        return Task.CompletedTask;
    });

    await _next(context);
}

OnStarting 将在响应标头写入线路之前被调用。这允许您在异常中间件处理后设置标头

【讨论】:

  • 是的,这行得通,谢谢。我读到了OnStarting(),但我不明白。是时候更仔细地阅读了。
  • 很奇怪,我有另一台电脑,当我从它访问网站时,我得到An item with the same key has already been added. Key: X-Frame-Options。我检查了其他设备 - 一切都很好,只是这台机器导致了问题。
  • 在您发布请求时可能与 XSRF(跨站请求伪造)有关?在这种情况下,AntiForgery 令牌/过滤器将启动。可能与stackoverflow.com/a/40526551/455493 相关。在这种情况下,您当然可能想要检查是否设置了标头并且不再设置它(或只是更改其值),或者在链接的答案中禁用防伪中间件上的标头
  • 很可能是这样。我已经添加了对已设置标题的检查,现在其他计算机也一切正常。再次感谢您。
猜你喜欢
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
相关资源
最近更新 更多