Firefox 在 ASP.NET Identity change/impersonate 上阻止简单的 CORS 请求

Firefox blocking simple CORS request on ASP.NET Identity change/impersonate

我正在与一些同事一起使用 ASP MVC 5 进行一个项目,我们正在使用来自 public CDN 的许多常见 Javascript 库。我已经配置并启用了 CORS,一切正常,除了这个特殊情况,我们在这一点上有点难过。

该应用程序使用 ASP.NET Identity 2,一些功能依赖于模拟功能。后端实现通常遵循此处的答案:How do I use ASP.NET Identity 2.0 to allow a user to impersonate another user?

前端使用带有防伪令牌的 AJAX post 到 WebAPI 端点(遵循此特定实现:)。为使新身份生效,该应用会执行 window.location.reload(true);

正是在这一点上,Firefox 阻止了所有 CORS 请求(所有这些请求都是对托管在 CDN 上的库和框架的请求)。这是特定错误(所有请求都相同,库不同,域相同):

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cdnjs.cloudflare.com/{some.js}. (Reason: CORS request did not succeed)

此问题仅发生在 Firefox 中。即使我尝试导航到应用程序中的不同页面,它也会继续阻止这些资源。除非我清除缓存(但不是 cookie,因此身份仍然存在),否则一切都很好。

这些资源的调用方式没有什么特别之处。这不是 POST 请求。它就在 <head> 中,例如:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

解决问题的方法(但就用户体验而言是不可接受的)

  1. 清除缓存(但不清除 cookie)

  2. 等待 5 分钟(让 Firefox 忘记?会话设置为 12 小时 服务器)

我真的不知道原因可能是什么,我很感激任何帮助我找到解决方法或线索的地方,我可以在哪里寻找解决方案。

这不是一个真正的答案,但我已经具体了解了我上面的案例是怎么回事。我有一个跟进问题,但在此之前我将分享我发现的内容:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Requests_with_credentials

When responding to a credentialed request, the server must specify an origin in the value of the Access-Control-Allow-Origin header, instead of specifying the "*" wildcard.

Because the request headers in the above example include a Cookie header, the request would fail if the value of the Access-Control-Allow-Origin header were "*". But it does not fail: Because the value of the Access-Control-Allow-Origin header is "http://foo.example" (an actual origin) rather than the "*" wildcard, the credential-cognizant content is returned to the invoking web content.

Note that the Set-Cookie response header in the example above also sets a further cookie. In case of failure, an exception—depending on the API used—is raised.

这正是正在发生的事情,因为在用户登录之前不会发生此问题。cdnjs(或任何其他 CDN)将发送通配符 header,因为这是它的标准完毕。

我仍然很困惑为什么脚本标签会发生这种情况,所以我的 follow-up 问题应该是这样的。