.NET Core 上 CORS 的意外行为

Unexpected behavior with CORS on .NET Core

我已将以下内容添加到我的服务配置中。

services.AddCors(options 
    => options.AddDefaultPolicy(builder 
        => builder
            //.AllowAnyHeader()
            .WithHeaders("header-that-nobody-knows")
            .WithOrigins("http://localhost:44304")));

我的预期是呼叫会反弹(因为我没有将 header-that-nobody-knows 添加到我的 headers)。但是,请求的执行就像设置了 AllowAnyHeader() 一样。

WithOrigins() 中操作端口、域或协议会产生预期的结果,因此配置似乎已正确连接。我怀疑这是一种特殊情况,因为在涉及 GETPOST[=32= 时,WithMetod() 出现了意想不到的行为](而其他方法 blocked/allowed 取决于传递的参数)。

检查 MSDN 没有任何我侦察到的解释。

我怀疑这是否重要,但为了完整起见,这里是调用该调用的 Angular 代码。

let url = "https://localhost:44301/security/corstest?input=blobb";
this.http.get<any>(url).subscribe(
  next => console.log("next", next),
  err => console.warn("err", err));

操作方法如下所示。

[HttpGet("corstest")]
public IActionResult CorsTest([FromQuery] string input)
{
    return Ok(new { data = input + " indeed..." });
}

当您尝试使用“non-standard”header 向 cross-origin URL 发送请求时, 浏览器将使用包含 non-standard headers.

Access-Control-Request-Headers header 执行预检 OPTIONS 请求
OPTIONS /corstest

Access-Control-Request-Method: GET
Access-Control-Request-Headers: header-that-nobody-knows
Origin: https://my.api

ASP.NET 核心检查这个值并检查 CORS 策略是否有 AllowAnyHeader 或者它是否明确允许 .WithHeaders,如果没有它会发出非 200 响应并且浏览器将拒绝发送实际请求。

因此,不向请求 headers 添加 header-that-nobody-knows 并不意味着 ASP.NET Core 将拒绝为请求提供服务,这意味着如果您设置 header-that-nobody-knows header 在 cross-origin 请求中,它 允许它而不是发出非 200 响应(假设您使用 WithHeaders 或 [=18 允许它=])

简而言之:

  • 您必须至少允许 some/all 个来源 + some/all headers 才能使 CORS 策略生效。
  • 浏览器希望预检请求中的 Access-Control-Allow-HeadersAccess-Control-Allow-Origin 与主请求匹配。
  • 您只能发送允许的 header 的子集(包括 0)。

参考资料