即使设置了跨源属性,Safari 也不会提示输入跨源脚本和链接标记的基本身份验证凭据



SO 已审核问题

我知道以下问题:

野生动物园:"被屏蔽 https://...更新到 Angular 8

野生动物园

另一方面,Safari(桌面[14.0.3]或移动[iOS 14])的行为有所不同。如果我的页面落后于基本身份验证,它会提示我输入凭据并开始呈现其内容,但是当引擎到达我的文件时,它不会提示我输入凭据,它会在控制台中记录一些错误消息,指出发生了401 UnauthorizedHTTP 错误,并且根据脚本,控制台还将包含一个错误,指出:

Blocked ... from asking for credentials because it is a cross-origin request.

到目前为止的分析

它可能看起来像一个混合内容(HTTPS包含在HTTPS页面中),但到目前为止我所讨论的所有内容都在HTTPS下,具有有效证书。

这似乎也是一个 CORS 问题,但实际上,服务器返回的401实际上确实包含所有需要的 CORS 标头:

HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
...
WWW-Authenticate: Basic realm="Fake Realm"

请注意,对scriptlink标记的文件请求GET请求,因此允许Access-Control-Allow-Origin: *

测试用例

我已经测试过:

  • scriptlink没有crossorigin属性的标记
  • scriptlink具有crossorigin属性的标记
  • scriptlink带有crossorigin="anonymous"标签
  • scriptlink带有crossorigin="use-credentials"的标签

以上所有功能在最新的Chromium和Firefox中都有效,但在macOS的Safari 14.0.3中不起作用,在iPadOS 14的Safari中不起作用,也不能在iOS 14的Safari中运行。

问题

我的问题是:有没有人在 Safari 中拥有这样的设置(经过基本身份验证的跨源资源)?你能告诉我的代码中可能导致此问题的原因吗(见下文)?

请注意,从"CDN"中删除身份验证不是一个选项。

所有这些都让我想到:

  • Safari 不支持此类请求(经过基本身份验证的跨源资源)
  • Safari的实现是不合规格
  • Chromium和Firefox的实现是不合规格
  • 的。

如何复制

我将以下示例留给您测试,它使用 HTTPBin 来模拟基本身份验证请求,该请求在 Chromium 和 Firefox 中提示输入凭据,但在 Safari 中无法提示。

用户:user
密码:passwd

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Safari basic authentication issue</title>
</head>
<body>
<!-- This emulates HTTP authentication and when correctly authenticated returns a JSON response which is invalid JS but this serves for the purpose of prompting for credentials -->
<script src="https://httpbin.org/basic-auth/user/passwd" crossorigin="use-credentials"></script>
</body>
</html>

根据 https://trac.webkit.org/changeset/228486/webkit/,问题中描述的 Safari 行为是有意为之的。具体来说,Safari 会阻止对页面子资源的跨源请求,并记录以下内容:

阻止<子资源>请求凭据,因为它是跨源请求。

https://trac.webkit.org/changeset/228486/webkit/提交消息给出了以下基本原理:

提示输入凭据以加载跨源子资源通常被导航到网页或与之交互的人员视为意外。这些子资源的跨源和隐式加载性质使得请求凭据变得可疑,因为它们不是由用户显式加载的页面的同一来源提供的,并且不保证对应于页面初始加载以外的显式用户交互。我们知道,请求凭据的子资源可能会被滥用为网络钓鱼攻击的一部分。不允许跨源子资源请求凭据似乎是合理的,因为它们的性质可疑且存在滥用风险。

2018年写的那条提交消息也提出了这样的主张:

这也将使 WebKit 的行为与 Chrome 的行为相匹配。

但是,虽然在2018年Chrome可能还阻止了子资源提示输入凭据,但对于Chrome 89来说并非如此。但是,对于Chrome 91来说,这似乎是正确的。因此,Chrome可能正在改变其行为,以执行与Safari相同的阻止。

所以我认为底线是:不可能让 Safari 提示输入子资源的凭据,并且假设提示输入子资源的凭据将继续在 Chrome 中工作(从长远来看,在 Firefox 中也是如此)。

最新更新