允许在您的站点中使用关联来源请求重复使用通行密钥

通行密钥与特定网站绑定,并且只能用于在创建它们的网站上登录。

这是在信赖方 ID (RP ID) 中指定的,对于为 example.com 域创建的通行密钥,RP ID 可以是 www.example.comexample.com

虽然 RP ID 阻止通行密钥被用作在任何地方进行身份验证的单一凭据,但它们为以下情况带来了问题:

  • 具有多个域名的站点:用户无法使用相同的通行密钥在同一公司管理的不同国家/地区特定域名(例如 example.comexample.co.uk)之间登录。
  • 品牌域名:用户无法在单个品牌使用的不同域名(例如 acme.comacmerewards.com)之间使用相同的凭据。
  • 移动应用:移动应用通常没有自己的域名,这使得凭据管理具有挑战性。

存在基于身份联合的解决方法,以及其他基于 iframe 的解决方法,但在某些情况下它们很不方便。关联来源请求提供了一种解决方案。

解决方案

借助关联来源请求,网站可以指定允许使用其 RP ID 的来源。

这为用户在您运营的多个站点之间重复使用相同的通行密钥解锁了可能性。

要使用关联来源请求,您需要在特定 URL https://{RP ID}/.well-known/webauthn 上提供一个特殊的 JSON 文件。如果 example.com 想要允许其他来源将其用作 RP ID,则应在 https://example.com/.well-known/webauthn 上提供以下文件:

{
    "origins": [
        "https://example.co.uk",
        "https://example.de",
        "https://example-rewards.com"
    ]
}

下次任何这些站点调用通行密钥创建 (navigator.credentials.create) 或身份验证 (navigator.credentials.get) 并使用 example.com 作为 RP ID 时,浏览器将注意到 RP ID 与请求来源不匹配。如果浏览器支持关联来源请求,它首先在 https://{RP ID}/.well-known/webauthn 查找 webauthn 文件。如果该文件存在,浏览器会检查发出请求的来源是否在该文件中被列入允许列表。如果是,则继续执行通行密钥创建或身份验证步骤。如果浏览器不支持关联来源请求,则会抛出 SecurityError

浏览器支持

  • Chrome:从 Chrome 128 开始支持。
  • Safari:从 macOS 15 beta 3 和移动设备 iOS 18 beta 3 开始支持。
  • Firefox:等待立场

以下演示使用两个站点 https://ror-1.glitch.mehttps://ror-2.glitch.me 为例。
为了使用户能够在这两个站点中使用相同的通行密钥登录,它使用关联来源请求允许 ror-2.glitch.me 使用 ror-1.glitch.me 作为其 RP ID。

演示

https://ror-2.glitch.me 实施了关联来源请求以使用 ror-1.glitch.me 作为 RP ID,因此 ror-1ror-2 在创建通行密钥或使用通行密钥进行身份验证时都使用 ror-1.glitch.me 作为 RP ID。
我们还在这两个站点之间实施了共享通行密钥数据库。

观察以下用户体验

  • 您可以在 ror-2 上成功创建通行密钥并使用通行密钥进行身份验证,即使其 RP ID 是 ror-1(而不是 ror-2)。
  • 一旦您在 ror-1ror-2 上创建了通行密钥,您就可以在 ror-1ror-2 上使用它进行身份验证。由于 ror-2ror-1 指定为 RP ID,因此从任何这些站点发出通行密钥创建或身份验证请求与在 ror-1 上发出请求相同。RP ID 是将请求与来源关联的唯一要素。
  • 一旦您在 ror-1ror-2 上创建了通行密钥,Chrome 可以在 ror-1ror-2 上自动填充它。
  • 在任何这些站点上创建的凭据都将具有 ror-1 的 RP ID。
Chrome autofills on both sites.
感谢关联来源请求,用户可以在 ror-1 和 ror-2 之间使用相同的通行密钥凭据。Chrome 也会自动填充凭据。

查看代码

步骤 1:实施共享帐户数据库

如果您希望用户能够在 site-1site-2 之间使用相同的通行密钥登录,请实施在这两个站点之间共享的帐户数据库。

步骤 2:在 site-1 中设置您的 .well-known/webauthn JSON 文件

首先,配置 site-1.com,使其允许 site-2.com 将其用作 RP ID。为此,请创建您的 webauthn JSON 文件

{
    "origins": [
        "https://site-2.com"
    ]
}

JSON 对象必须包含名为 origins 的键,其值是一个或多个包含 web 来源的字符串数组。

重要限制:最多 5 个标签

将处理此列表中的每个元素以提取 eTLD + 1 标签。例如,example.co.ukexample.de 的 eTLD + 1 标签均为 example。但 example-rewards.com 的 eTLD + 1 标签为 example-rewards。在 Chrome 中,标签的最大数量为 5。

步骤 3:在 site-1 中提供您的 .well-known/webauthn JSON

然后,在 site-1.com/.well-known/webauthn 下提供您的 JSON 文件。

例如,在 express 中

app.get("/.well-known/webauthn", (req, res) => {
  const origins = {
    origins: ["https://site-2.com"],
  };
  return res.json(origins);
});

在这里,我们使用 express res.json,它已经设置了正确的 content-type ('application/json');

步骤 4:在 site-2 中指定所需的 RP ID

在您的 site-2 代码库中,在所有需要的地方将 site-1.com 设置为 RP ID

  • 在凭据创建时
    • 在传递给 navigator.credentials.create 前端调用的凭据创建 options 中,将 site-1.com 设置为 RP ID,并且通常在服务器端生成。
    • 在您运行凭据验证以将其保存到数据库之前,将 site-1.com 设置为预期的 RP ID。
  • 在身份验证时
    • 在传递给 navigator.credentials.get 前端调用的身份验证 options 中,将 site-1.com 设置为 RP ID,并且通常在服务器端生成。
    • 在您运行凭据验证以在服务器上验证用户身份之前,将 site-1.com 设置为要验证的预期 RP ID。

故障排除

Error message popup in Chrome.
在 Chrome 中创建凭据时出现错误消息。如果在 `https://{RP ID}/.well-known/webauthn` 找不到您的 `.well-known/webauthn` 文件,则会抛出此错误。
Error message popup in Chrome.
在 Chrome 中创建凭据时出现错误消息。如果可以找到您的 `.well-known/webauthn` 文件,但未列出您尝试从中创建凭据的来源,则会抛出此错误。

其他注意事项

在站点和移动应用之间共享通行密钥

关联来源请求允许您的用户在多个站点之间重复使用通行密钥。要允许您的用户在网站移动应用之间重复使用通行密钥,请使用以下技术:

在站点之间共享密码

关联来源请求允许您的用户在站点之间重复使用通行密钥。在站点之间共享密码的解决方案因密码管理器而异。对于 Google 密码管理器,请使用数字资产链接。Safari 具有不同的系统

凭据管理器和用户代理的作用

这超出了您作为站点开发者的范围,但请注意,从长远来看,RP ID 不应成为用户代理或用户使用的凭据管理器中用户可见的概念。相反,用户代理和凭据管理器应向用户显示其凭据已在何处使用。此更改需要时间才能实施。临时解决方案是同时显示当前网站和原始注册网站。