在 cross-origin iframe 中使用 `navigator.credentials.get()` 会出现错误“'publickey-credentials-get' 功能未在此文档中启用”

Using `navigator.credentials.get()` in cross-origin iframe gives error "'publickey-credentials-get' feature is not enabled in this document"

通过 webauthn 登录 iframe 时出现错误。

The 'publickey-credentials-get' feature is not enabled in this document. Permissions Policy may be used to delegate Web Authentication capabilities to cross-origin child frames.

这里是 link 示例 https://jsfiddle.net/14kj25nr/。我直接通过webauthn.io注册了一个用户“test_account”,然后尝试通过jsfiddle登录。它说要使用 publickey-credentials-get,但我找不到使用它来让它工作的方法。任何帮助将不胜感激。

更新 1:

我已经为 iframe 添加了允许属性 allow="publickey-credentials-get"。它仍然给我同样的错误。 fiddle 中的示例已更新。

更新 2:

根据 IAmKale 的建议。我进行了以下更改,但仍然出现相同的错误。 更新了 iframe allow="publickey-credentials-get *".

的允许属性

我使用 Requestly chrome 扩展在 RP 的响应中添加 Permissions-Policy header。在下面的屏幕截图中可以看出,我能够在响应中成功添加 header 。但仍然出现相同的错误。会不会是某个 jsfiddle 特定问题?还是我做错了什么?我正在使用 Chrome 版本 96.0.4664.110。

更新 3:

当我在本地主机中使用 iframe 而不是 jsfiddle 时,我得到了 webauthn chrom pop-up。但是log-in还是不成功,服务器returnsPOST https://webauthn.io/assertion 400.

The Web Authentication API is disabled by default in cross-origin iframes. To override this default policy and indicate that a cross-origin iframe is allowed to invoke the Web Authentication API's [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) method, specify the allow attribute on the iframe element and include the publickey-credentials-get feature-identifier token in the allow attribute’s value.

https://www.w3.org/TR/webauthn-2/#sctn-iframe-guidance

扩展 Tim 的回答,嵌入 RP 的站点需要添加以下 allow 属性:

<iframe src="..." allow="publickey-credentials-get *" />

规范对此有点模棱两可,但深入研究 Permissions Policy 我相信 RP 还需要在对 URL 的响应中设置以下 HTTP header在 iframe 中指定的 src:

Permissions-Policy: publickey-credentials-get=*

如果您想要更精细的控制,您可以将允许嵌入 RP 站点的特定 URL 列入白名单:

# Only specific sites
Permissions-Policy: publickey-credentials-get=("https://example.com")

https://example.com 是在 <iframe>

中嵌入 RP 站点的页面的 URL

一旦两部分都准备就绪,我想您就可以在 iframe 中触发 navigator.credentials.get()