设备绑定会话凭据

W3C 首次公开工作草案,

关于本文档的更多详情
本版本:
https://www.w3.org/TR/2025/WD-dbsc-1-20250821/
最新发布版本:
https://www.w3.org/TR/dbsc/
编辑草案:
https://w3c.github.io/webappsec-dbsc/
历史记录:
https://www.w3.org/standards/history/dbsc-1/
反馈:
public-webappsec@w3.org ,主题行为 “[dbsc] … 消息主题 …” (存档
GitHub
编辑:
(Google)
(Google)
(Google)

摘要

设备绑定会话凭据(DBSC)旨在通过构建一种协议和基础设施,使用户代理能够断言其拥有安全存储的私钥, 从而防止通过 Cookie 窃取进行的劫持。DBSC 是一个 Web API,也是一种用于在用户代理和服务器之间实现这种绑定的协议。

本文档的状态

本节描述本文档在发布时的状态。 当前 W3C 出版物以及本技术报告最新修订版的列表 可在 W3C 标准与草案 索引中找到。

本文档由 Web 应用安全 工作组作为首次公开工作草案发布,并使用 推荐标准轨道。本文档 旨在成为一项 W3C 推荐标准。

已归档的)公共邮件列表 public-webappsec@w3.org (参见说明) 是讨论本规范的首选方式。 发送电子邮件时, 请在主题中包含文本 “dbsc”, 最好采用如下形式: “[dbsc] …评论摘要…

本文档是首次公开工作草案

作为首次公开工作草案发布并不表示 W3C 及其成员认可本文档。本文档是草案文档,可能随时被 更新、替换或 由其他文档取代。除作为进行中的工作外,不宜引用 本文档。

本文档由 Web 应用安全工作组制作。

本文档由一个依据 W3C 专利政策运作的工作组制作。 W3C 维护着一个与该组交付成果相关的任何 专利披露的公开列表; 该页面还包含披露专利的说明。 实际知晓某项专利、且认为该专利包含必要权利要求的个人, 必须按照 W3C 专利政策第 6 节披露该信息。

本文档受 2025年8月18日 W3C 流程文档约束。

1. 引言

本节不是规范性的。
请注意,这只是用于撰写协作的非常早期草案

Web 建立在无状态协议之上。为了为某些 功能维护状态,Web 应用会在用户设备上本地存储数据。这种 存储可以持续很长时间,并用于安全敏感数据,例如已登录用户会话的凭据。

一般而言,在常见操作系统上,用户代理没有办法以一种能抵御与 用户代理本身拥有同等权限的软件的方式存储这类数据。同时, 由这些数据认证的操作可能会产生严重后果,例如从银行账户转账。此模型面临的一种 常见且可扩展的威胁是恶意软件外泄此类 凭据并在别处实施滥用,从而规避检测。

本文档定义了一种新的 API,Device Bound Sessions Credentials(DBSC),它 使服务器能够验证会话凭据并未从 设备导出。这些凭据是私钥,因此用户代理可以使用 TPM 或类似 API 等设施,来保护它们即使面对同等权限的恶意软件也不会被外泄。

目标是在提供用户已经习惯的 用例的同时,为用户提供安全且受保护的体验。同时,我们希望确保 尊重用户隐私,本协议不会泄漏新的隐私标识符。该 API 特别注意与现有 服务器端认证栈轻松集成,为此类保护提供渐进式路径,而 不需要重写 Web 软件栈的大部分内容。

2. 安全考量

DBSC 的目标是通过提供一种替代 长期 cookie 持有者令牌的方案来减少会话窃取,并允许会话认证 基于可更好防止外泄的私钥。 这会使互联网对用户更安全,因为用户身份被滥用的可能性更低, 恶意软件被迫在本地行动,因此更容易被检测和缓解。

用户代理实现负责选择保护 此类私钥免于外泄的最佳方式,并考虑不同平台上存在的恶意软件威胁类型 以及现有保护机制。这 包括但不限于 TPM 或安全元件等安全硬件、 操作系统提供的安全密钥生成和管理 API,或能针对本地运行的恶意软件 提供合理保护的进程隔离机制。

只要会话有效并注册到未受攻陷的设备, 主机就可以凭借密码学确定性知道会话密钥受到保护, 不会被恶意外泄到其他设备。

2.1. 非目标

当攻击者驻留在用户设备上时,DBSC 不会阻止其临时访问 浏览器会话。私钥应尽现代操作系统所允许的方式安全存储, 防止会话私钥被外泄, 但签名能力很可能仍可供以该用户身份在该用户设备上运行的任何程序使用。

如果攻击者在会话注册时替换或注入 用户代理,DBSC 也不会阻止攻击,因为攻击者可以将 会话绑定到未受 TPM 绑定的密钥,或绑定到攻击者 永久控制的 TPM。

DBSC 并非设计用于向主机提供任何关于 会话注册到的具体设备或该设备状态的保证。

3. 隐私考量

DBSC 协议的隐私目标是不引入额外的用户 跟踪表面:实现此 API(对浏览器而言)或启用它(对网站而言) 不应带来任何重大的用户隐私权衡。

为确保这一点而采取的一些考量:

3.1. Cookie 考量

站点应不可能使用此 API 绕过同源 策略、第三方 cookie 策略等。由于当前和不断变化的 cookie 行为具有复杂性,且 DBSC 与 cookie 紧密集成,当前 方案是每个用户代理都应对 DBSC 使用与其对 cookie 使用的相同策略。如果基于用户设置、已应用策略或用户代理实现细节, DBSC cookie 凭据不会适用于某个网络请求, 那么任何额外的 DBSC 行为也同样不会适用。这确保实现 DBSC 不会带来新的隐私 行为。

3.2. 计时侧信道泄漏

如果第三方 cookie 已启用,攻击者可以通过测量请求耗时来判断 用户是否已认证。 这是因为刷新可能相当慢,尤其是当它依赖于用于密钥保护的缓慢底层设施 (例如 TPM)时。

这通过会话配置中的 allowed_refresh_initiators 键来缓解, 该键可用于严格限制哪些站点能够触发 DBSC 刷新。它不能被现有方案 (例如 X-Frame-Options)取代,因为现有方案只在 请求完成后才适用,而 DBSC 必须在 请求开始前选择是否刷新。

3.3. 联合会话

许多站点使用没有浏览器参与的联合登录机制, 经常依赖链接装饰(例如 OIDC)。为了实现 DBSC 易于采用的目标,我们希望这些站点能够保护自己 免受 cookie 窃取,而无需完全重写其认证流程。理想情况下, Relying Parties(RP)可以简单地独立于 Identity Provider(IdP)建立 DBSC 会话。不幸的是,如果 用户已经登录,大多数 IdP 不要求密码。如果不需要用户交互,恶意软件就可以 利用其对用户机器的临时访问来模拟登录流程,并 使用恶意软件创建且可外泄的新私钥建立 DBSC 会话。 这违反了 DBSC 的安全目标。

由于 DBSC 并不内在绑定到登录或身份,Identity Provider 不是最准确的术语。因此我们使用术语 Session Provider(SP),尽管 在目标用例中,我们预期 SP 和 IdP 是同一方。

为了保护 RP 的会话,我们需要以某种方式链接 RP 和 SP 会话。 最简单的方法是让 SP 和 RP 使用相同的 会话密钥对。由于我们假设 SP 的会话是在 恶意软件攻陷设备之前建立的,因此我们信任私钥会被 安全存储。但跨站点共享密钥具有复杂的隐私属性。为了 缓解共享高熵标识符的隐私风险,我们要求 RP 已经知道 SP 会话的公钥和会话标识符。RP 将在 `Secure-Session-Registration` 标头中包含 SP URL、会话标识符以及 base64 编码的 JWK thumbprint(参见 [RFC4648][RFC7638])。如果密钥正确,用户代理 将在 RP 上创建一个与 SP 上会话使用相同密钥的新会话。

恶意 RP 和 SP 还存在潜在风险,它们可能协作尝试在 RP 和 SP 本不应已经共享信息的情况下识别用户 (例如存在针对指纹识别或链接装饰的保护时)。 RP 可以简单地尝试猜测许多公钥,直到找到匹配项, 从而获得用户的唯一标识符。这会允许协作的 RP 和 SP 在站点之间共享用户身份,超出预期的跨站点身份链接机制。 为防止这一点,用户代理应对注册尝试加入 显著的退避或配额(这也建议用于避免对 TPM 造成拒绝服务)。 请注意,DBSC 的安全属性依赖于一个密码学假设: 很难让两个用户拥有相同的密钥对,因此查询用户在 SP 上是否拥有特定 DBSC 公钥所提供的信息远小于一比特熵。

为了进一步限制成功揭示用户身份的价值,我们还要求 SP 通过 .well-known 进行选择加入。浏览器应限制该列表中的 RP 来源数量。我们还需要防止 RP 使用 多个 SP 并以这种方式聚合身份。为此,我们要求 RP 也在 .well-known 中声明其 SP。二者结合将确保 大型站点群无法在高价值用户浏览 Web 时协作揭示其身份。

假设 example.com 的所有者也运营 example.co.uk。登录始终 发生在 example.com,并通过链接 装饰传播到 example.co.uk。为了用 DBSC 会话保护这两个站点, example.com 应继续使用其现有的 `Secure-Session-Registration` 标头:
Secure-Session-Registration: (ES256);path="/register";challenge="challenge"

在将 DBSC 会话扩展到 example.com.uk 时,该站点应向 `Secure-Session-Registration` 标头追加新的参数:

Secure-Session-Registration: (ES256);path="/register";challenge="challenge";provider_key="abc";provider_id="example.com id";provider_url="https://example.com"

假设 example.comexample.co.uk 具有适当的 .well-known 条目,这将导致 example.co.uk 使用 与 example.com 上会话相同的密钥注册新的 DBSC 会话。这允许 DBSC 保护 example.co.uk,而无需用户在登录时重新向 example.com 认证。

4. 已考虑的替代方案

4.1. WebAuthn 和静默中介

WebAuthn 为站点提供某些密钥管理能力,因此它可能可以 扩展以满足与 DBSC 相同的目标。我们不采用此 方法,因为 WebAuthn 对交互式用户登录的关注,使其 API 具有若干与 DBSC 这类功能目标相反的属性。例如, WebAuthn 凭据并不绑定到特定会话。它们 被设计为长期存在,并且不会随站点数据一同清除。这与会话 密钥所需的隐私属性并不匹配。类似地,WebAuthn 凭据 设计用于明确用户意图。扩展 WebAuthn 以涵盖 DBSC 提供的功能,将要求 WebAuthn 建立一种可静默使用的 不同类型密钥。这会为 WebAuthn 和 DBSC 都引入额外复杂性。因此, 我们的立场是 WebAuthn 旨在提供安全登录,而 DBSC 是 互补的,在登录后保护用户。

5. 服务器考量

为了使用 DBSC,站点所有者需要建立两个新端点: 注册端点和刷新端点。

浏览器在收到 `Secure-Session-Registration` 标头后,会异步联系注册端点。此端点应:

刷新端点敏感得多。每当请求携带过期的绑定 cookie 时, 都会联系此端点,并且其响应会阻塞 原始请求。未能响应或恢复绑定 cookie 可能 导致浏览器代理启动拒绝服务防护机制,甚至 终止会话。二者都可能导致后续请求没有绑定 cookie。此端点的预期行为是:

浏览器可以选择主动刷新会话,以尝试最小化站点采用 DBSC 带来的延迟成本。站点不应假设刷新只会在 绑定 cookie 过期时发生。

如果允许跨站点 fetch,刷新端点很可能会通过计时侧 信道直接泄漏登录状态。服务器可以检查有效的 `Sec-Secure-Session-Id` 标头,以确保传入请求由用户代理发起, 而不是跨站点请求。还建议在此端点上设置 狭窄的 CORS 策略,并且不要允许跨站点来源携带凭据发起 请求。DBSC 的 CORS 集成已设计为通过在延迟 请求携带凭据时隐式包含凭据来实现这一点。出于类似原因, 还建议刷新端点通过 X-Frame-OptionsCross-Origin-Resource-Policy 标头拒绝被嵌入。

假设 example.com 有两个端点:

该站点希望 DBSC 保护对 /authenticated 的跨站点请求,并且 认为此单一端点上的计时侧信道风险 很小。如果我们没有隐式允许由用户代理触发的刷新请求携带 凭据,那么 /refresh 将需要为任何请求来源返回 Access-Control-Allow-Credentials。这样攻击者 就可以直接 fetch /refresh 来泄漏登录状态。

由于 DBSC 对 /refresh 的调用会隐式允许凭据,/refresh 端点可以拒绝永远返回 Access-Control-Allow-Credentials。它仍会 在 DBSC 刷新的上下文中收到带凭据的请求。其他 站点将无法直接携带凭据 fetch 该端点, 从而防止登录状态发生简单的跨站点泄漏。

使用 DBSC 进行联合登录的站点(见 § 3.3 联合会话)应 确保只接受具有联合密钥的会话。联合 会话的安全性依赖于机器在 Session Provider(SP)登录时未被攻陷,因为恶意软件可以利用对机器的临时访问 在 Relying Party(RP)上用新密钥注册会话。因此 RP 应 只接受使用从 SP 收到的适当公钥注册的会话。

6. 用户代理考量

DBSC 为浏览器调度 cookie 刷新提供了很大的灵活性。这可以缓解 DBSC 的延迟并降低 TPM 和服务器负载。我们建议用户代理按以下方式调度 cookie 刷新:

7. 框架

本文档使用 ABNF 语法指定句法,如 [RFC5234] 中定义,并由 [RFC7405] 更新,同时使用 第 7 节 中定义的 #rule 扩展,该节来自 [RFC9112],以及同一文档 第 3.2.6 节 中定义的 quoted-string 规则。

本文档依赖 Infra Standard 中用于其算法和正文的若干基础 概念 [INFRA]

7.1. 会话存储

用户代理维护一个会话 存储。它是一个从有序映射按 id 的会话映射 的映射,键为可注册域。会话应在 用户代理重启后继续持久存在。

7.2. 按 id 的会话

按 id 的会话映射是一个有序 映射,对于给定的可注册域,它从 会话标识符映射到设备绑定会话

7.3. 设备绑定会话

设备绑定 会话是一个结构体,具有以下
会话标识符

一个字符串, 是某个 可注册域上会话的唯一标识符

刷新 URL

一个字符串,表示用于刷新 会话的 URL

已缓存 challenge

一个字符串或 null,将用作此 会话的下一个 challenge

会话范围

一个会话范围,定义 哪些 URL 在此会话范围内

会话凭据

一个列表,包含该会话使用的会话 凭据,从 JSON 会话凭据派生

过期时间戳

一个时刻,此会话应在该时刻被移除

会话密钥对

会话使用的密钥对。私钥 应以安全方式存储(见 § 2 安全 考量)。

允许的刷新发起者

一个列表,包含 描述哪些主机允许发起 DBSC 刷新的字符串。详见 § 8.3 识别请求是否允许 刷新

7.4. 会话范围

会话范围是一个结构体,具有以下
origin

此会话为其注册的来源

include site

一个布尔值,指示该会话适用于整个站点还是仅适用于某个 来源

范围规范

一个列表,包含 此会话使用的范围 规范

7.5. 范围规范

范围规范 是一个结构体,具有 以下
type

一个字符串,为 "include" 或 "exclude",定义此结构体中 定义的项应添加到范围还是从范围中移除

host

一个字符串,定义此 范围规范适用时必须匹配的域名或域名模式

path

一个字符串,定义此范围规范的路径部分

7.6. 会话凭据

会话凭据是 一个结构体,具有 以下
name

一个字符串,定义凭据 cookie 的名称

attributes

一个字符串,定义凭据 cookie 的其他属性。 用户代理应在这里提供与其为 cookie 提供的默认值相同的默认值。

7.7. 可注册来源标签

可注册来源 标签是该可注册域的第一个 域 标签,或者如果可注册域为 null,则为 null。例如,如果 co.ukde 都是公共后缀,那么 example.co.ukwww.example.de可注册来源标签都是 example

8. 算法

8.1. 识别会话

此算法描述如何从用户代理上存在的所有 会话中识别会话会话标识符可注册域内唯一。

给定一个 URLurl)和会话标识符session identifier),此算法返回一个设备绑定会话;如果不存在此类会话,则返回 null。

  1. domainurlhost可注册域

  2. 如果用户代理的会话存储包含 domain, 返回 null。

  3. domain sessions 为用户代理的会话存储[domain],作为一个 按 id 的 会话映射

  4. 返回 domain sessions[session identifier] 并以 null 作为默认值

8.2. 识别 URL 是否在会话范围内

此算法描述如何确定 URL 是否在范围内,该范围属于某个设备绑定会话。给定一个 URLURL)和 设备绑定 会话session),如果 URL 在范围内,则返回 "include", 否则返回 "exclude"。
  1. scopesession会话范围

  2. 如果 scopeinclude site 为 true,且 URLoriginscopeorigin 不是同站点, 则返回 "exclude"。

  3. 如果 scopeinclude site 为 false,且 URLoriginscopeorigin 不是同源, 则返回 "exclude"。

  4. 如果 URL 匹配 session刷新 URL,返回 "exclude"。

  5. 对每个 scope specification,该项在 scope范围规范中:

    1. host patternscope specificationhost,并 令 path patternscope specificationpath

    2. 如果对 URLhosthost pattern 运行 § 8.4 识别主机是否匹配 模式返回 false,继续

    3. 如果满足以下任一条件,返回 scope specificationtype

      1. URLpath 恰好是 path pattern

      2. path pattern 以 '/' 结尾,并且 URLpathpath pattern 开头。

      3. URLpathpath pattern 后跟 '/' 的形式开头。

  6. 返回 "include"。

8.3. 识别请求是否允许刷新

此算法描述如何为某个设备绑定 会话确定 请求是否允许触发刷新。给定一个请求request)和设备绑定会话session),如果 request 可以触发刷新,则返回 "allowed", 否则返回 "disallowed"。
  1. 如果 session会话范围include site 为 true,且 requestoriginsession会话范围origin 同站点,返回 "allowed"。

  2. 如果 session会话范围include site 为 false,且 requestoriginsession会话范围origin 同源,返回 "allowed"。

  3. 对每个 initiator pattern,该项在 session允许的刷新发起者中:

    1. 如果对 requestoriginhostinitiator pattern 运行 § 8.4 识别主机是否匹配 模式返回 true,则返回 "allowed"。

  4. 返回 "disallowed"。

8.4. 识别主机是否匹配模式

此算法描述如何确定 主机是否匹配模式。它接受一个hosthost)和 一个字符串pattern)作为输入。如果 pattern 覆盖 host,则返回 true。
  1. 如果 pattern 等于 '*',返回 true。

  2. host string 为序列化后的 host

  3. 如果 pattern 以 '*' 开头,且 host 是一个

    1. 如果 pattern 不以 '*.' 开头,返回 false。

    2. 如果 host stringpattern 去掉第一个字符后的全部内容结尾, 返回 true。

  4. 如果 host string 等于 pattern,返回 true。

一些模式匹配示例:
  • example.com 匹配 *

  • example.com 匹配 example.com

  • example.com 不匹配 *.example.com

  • subdomain.example.com 匹配 *.example.com

8.5. 识别需要刷新的会话

给定一个请求request),此算法描述如何识别需要刷新的会话。如果存在任何此类 会话,它应阻止 request 继续进行。
  1. domainrequesturlhost可注册域

  2. 如果用户代理的会话存储包含 domain, 返回 null。

  3. domain sessions 为用户代理的会话存储[domain],作为一个 按 id 的 会话映射

  4. 对每个 session,该项在 domain sessions 中:

    1. 如果 session过期时间戳早于当前时间, 从 domain sessions 中移除 session继续

    2. idsession会话标识符

    3. 如果元组domain, id)在 request延迟的设备绑定会话 ids中,继续

    4. requestURLsession 运行 § 8.2 识别 URL 是否在 会话范围内 中的步骤。如果结果不是 "include",继续

    5. requestsession 运行 § 8.3 识别请求是否 允许刷新 中的步骤。如果结果不是 "allowed",继续

    6. requestsession会话凭据运行 § 8.6 识别是否 缺少会话凭据。 如果结果为 false,继续

    7. 将(domain, id)添加到 request延迟的设备绑定 会话 ids

    8. session过期时间戳设置 为未来的时间戳。过期时间戳的 具体选择由用户代理决定。建议 与最大 cookie 生命周期对齐。

    9. 返回 session

  5. 返回 null。

8.6. 识别是否缺少会话凭据

此算法描述如何识别 请求是否缺少会话凭据。给定一个请求request) 和一个列表,其中包含会话凭据credentials),返回一个 布尔值, 指示 credentials 中是否有任何 credentialrequest 上缺失。
  1. 对每个 credential,该项在 credentials 中:

    1. 如果具有 credentialattributes 的 cookie 不会附加到 request(见 第 5.4 节, 来自 [COOKIES]),继续

    2. 如果 requestheader list 包含一个 cookie,且 满足以下所有条件,继续

      1. cookie 的名称匹配 credentialname

      2. cookie 的以下所有属性都匹配 credentialattributes中的属性:Domain、Path、 Secure、HttpOnly、SameSite。

    3. 返回 true。

  2. 返回 false。

8.7. 缓存 challenge

此算法描述如何 处理 challenge,该 challenge 在 HTTP 标头中接收。

给定一个响应response),此算法更新某个设备绑定 会话已缓存 challenge

  1. header name 为 "Secure-Session-Challenge"。

  2. challenge list 为在 responseheader list上,给定 header name 和 "list" 执行获取结构化 字段值所得的结果。

  3. 如果 challenge list 为 null,返回。

  4. 对每个challenge, params),该项在 challenge list 中:

    1. 如果 challenge 的类型不是 sf-string继续

    2. session id 为 null。

    3. 如果 params["id"] 存在且是 sf-string,将 session id 设为 params["id"]。

    4. 如果 session id 为 null,继续

    5. session 为给定 responseURLsession id 运行 § 8.1 识别会话 所得的结果。

    6. 如果 session 为 null,继续

    7. 对每个 credential,该项在 session会话凭据中:

      1. 如果具有 credentialattributes 的 cookie 不能被 response 设置(见 第 5.3 节, 来自 [COOKIES]),继续

      2. challenge 存储为 session已缓存 challenge,以便下次 从此设备绑定 会话发送DBSC 证明时使用。

      3. 中断

8.8. 发送请求

此算法描述如何为设备绑定会话注册或刷新 发送 请求。它接受以下输入:一个请求originating request)、key pairURLdestination), 以及可选的字符串 session idchallengeauthorization

每当绑定凭据缺失时,用户代理会执行这些步骤, 但 MAY 在任何时候执行。主动在绑定 凭据过期之前发送请求可以最小化 DBSC 的延迟成本。

  1. 用户代理 MAY 跳过此请求,以防止对用户或站点造成拒绝服务。 例如,当此会话正在请求过多 TPM 操作(损害用户)或刷新 端点最近不可达(对站点存在拒绝服务风险)时,可能会发生这种情况。 如果用户代理选择这样做,它应使用 originating request、适当的 token(见 § 9.5 `Secure-Session-Skipped` HTTP 标头 字段中的选项)和 session id 执行 § 8.12 添加 debug 标头 的步骤, 以向站点指示这一点。

  2. terminate the session 为具有以下步骤的算法:

    1. 如果 session id 为 null,返回。

    2. 从用户代理的会话存储中移除具有如下域和标识符的会话: 该域为 destinationhost可注册域,标识符为 session id,如果找到此类会话。

  3. 如果 originating requestURLorigindestinationorigin不是同站点,返回。

  4. signed challenge 为 null。如果 challengeauthorization 非 null,创建一个DBSC 证明,使用 key pair 对其签名,并将 结果存储到 signed challenge 中。

  5. 创建一个用于 HTTP fetchrequest

  6. requestmethod 设为 "POST"。

  7. requestURL 设为 destination

  8. requestredirect mode 设为 "follow"。

  9. 如果 signed challenge 非 null,将标头 ("Secure-Session-Response", signed challenge) 追加requestheader list

  10. 如果 session id 非 null,将标头 ("Sec-Secure-Session-Id", session id) 追加requestheader list

  11. 如果 authorization 非 null,将标头 ("Authorization", authorization) 追加requestheader list

  12. requestinitiator 设为 originating requestinitiator

  13. requestorigin 设为 originating requestorigin

  14. response 为对 request 运行 HTTP fetch 的结果。

  15. 如果 response网络错误,或 responsestatus 为 407 或 429,返回。

  16. 如果 responsestatus 至少为 300 且小于 400,则 返回。

  17. 如果 responsestatus 为 403:

    1. 如果 session id 为 null,返回。

    2. session 为对 destinationsession id 运行 § 8.1 识别会话 中步骤的结果。

    3. 如果 session 为 null,返回。

    4. 否则,用原始输入重新开始此算法,但将 challenge 替换为 session已缓存 challenge

  18. 如果 responsestatus 至少为 400 且小于 500, 则执行 terminate the session 并返回。

  19. 如果 responsestatus 至少为 500,则 返回。用户代理可以选择在此会话后续刷新请求上触发退避机制, 以限制刷新端点临时故障造成的损害。

  20. 如果 session id 非 null,且 responsebody 为空,返回。

  21. responsedestinationsession idkey pair 调用 § 8.9 创建会话

8.9. 创建会话

为了因注册请求到 destination(一个 URL)的 response (一个响应)而为 session id(一个字符串或 null)并使用 key pair 创建会话,执行以下 步骤:
  1. terminate the session 为具有以下步骤的算法:

    1. 如果 session id 为 null,返回。

    2. 从用户代理的会话存储中移除具有如下域和标识符的会话: 该域为 destinationhost可注册域,标识符为 session id,如果找到此类会话。

  2. JSON session 为将 responsebody 解析为JSON 会话指令的结果。如果解析失败, 执行 terminate the session 并返回。这包括验证所有必需键均已 存在。

  3. 如果 JSON sessioncontinue 为 false, 执行 terminate the session 并返回。

  4. session identifierJSON sessionsession_identifier

  5. JSON scopeJSON sessionscope

  6. origin 为从 JSON scopeorigin(如果存在)构造的来源;如果不存在,则为 destination 的来源。

  7. 如果 JSON sessionrefresh_url没有 值,令 refresh URLdestination

  8. 否则,令 refresh URL 为用 JSON sessionrefresh_url 的值相对于 destination 解析所得的结果。

  9. 执行以下验证。如果任一失败, 执行 terminate the session 并返回。

    1. 如果 session id 非 null,它必须匹配 session identifier

    2. origin 必须是有效的非不透明来源。

    3. origin 必须与 destinationorigin同站点

    4. refresh URL 必须具有 HTTPS 方案或为 localhost。

    5. refresh URLorigin 必须与 destinationorigin同站点

    6. 所有JSON 会话凭据都不得具有 属性 "Partitioned"。

  10. destination domaindestinationhost可注册域

  11. 如果 JSON scopeinclude_site 为 true,执行 以下验证。如果任一失败,执行 terminate the session 并返回。

    1. originhost必须等于 destination domain

    2. 如果 destination domain 等于 destinationhost,跳过此步骤中所有剩余验证。

    3. 如果 session id 非 null,跳过此 步骤中所有剩余验证。

    4. 否则,令 well known URLdestination 的副本,将 host 替换为 destination domain, 并将path 替换为 "/.well-known/device-bound-sessions"。

    5. well known response 为 fetch well known URL 的结果。

    6. well known responsestatus 必须为 200。

    7. well known responsebody 必须是 JSON 编码的 字典。

    8. well known responsebody 必须包含键 "registering_origins"。

    9. 键 "registering_origins" 的值必须包含 destination 的来源。

  12. session 为一个新会话。

  13. session会话标识符设为 session identifier

  14. session刷新 URL设为 refresh URL

  15. session会话范围设为一个新范围,其 originorigin,且 include siteJSON scopeinclude_site 的值。

  16. 对每个 JSON scope rule,该项在 JSON scopescope_specification中:

    1. scope rule 为一个新的范围规范

    2. scope ruletype设为 JSON scope ruletype

    3. scope rulehost设为 JSON scope ruledomain

    4. scope rulepath设为 JSON scope rulepath

    5. scope rule 追加到 session会话范围范围规范中。

  17. 对每个 JSON session credential,该项在 JSON sessioncredentials中:

    1. session credential 为一个新的会话凭据

    2. 如果 JSON session credentialtype 不是 "cookie",执行 terminate the session 并返回。

    3. session credentialname设 为 JSON session credentialname

    4. session credentialattributes设为 JSON session credentialattributes

    5. session credential 追加到 session会话凭据中。

  18. session会话密钥对设为 key pair

  19. session允许的刷新发起者 设为 JSON sessionallowed_refresh_initiators

  20. session过期时间戳设为未来 时间戳。过期时间戳的 具体选择由用户代理决定。建议 与最大 cookie 生命周期对齐。

  21. 对每个 credential,该项在 session会话凭据中:

    1. 如果具有 credentialattributes 的 cookie 不能被 response 设置(见 第 5.3 节, 来自 [COOKIES]),继续

    2. 调用 terminate the session 以移除现有会话。

    3. 将用户代理的会话存储[destination domain][session identifier] 设为 session

    4. 中断

8.10. 处理会话注册

为了因某个响应response)对于一个请求request)而处理会话 注册,执行以下步骤:
  1. header name 为 "Secure-Session-Registration"。

  2. registration list 为在 responseheader list中给定 header name 和 "list" 执行获取结构化 字段值所得的结果。

  3. 如果 registration list 为 null,返回。

  4. 对每个registration entry, params) ,该项在 registration list 中:

    1. 如果 registration entry 不是 sf-inner-list继续

    2. 如果 params["path"] 不存在,或其类型不是 sf-string继续

    3. pathparams["path"]。

    4. challenge 为 null,并令 authorization 为 null。

    5. 如果 params["challenge"] 或 params["authorization"] 中任一个存在 但 类型不是 sf-string继续

    6. 如果 params["challenge"] 存在,将 challenge 设为 params["challenge"]。

    7. 如果 params["authorization"] 存在,将 authorization 设为 params["authorization"]。

    8. endpoint 为相对于 response 的 URL 解析 path 所得的结果。

    9. key pair 为对 registration entryparamsendpoint 运行 § 8.11 创建会话密钥对所得的结果。

    10. 如果 key pair 为 null,返回。

    11. 使用 requestkey pairendpoint、 作为 null 的 session identifier、challengeauthorization 调用 § 8.8 发送请求

8.11. 创建会话密钥对

此算法描述如何创建 会话密钥对,包括 Relying Party 与 Session Provider 之间的密钥共享。它接受 `Secure-Session-Registration` 标头的 registration entryparams,以及注册端点的URLregistration URL)作为输入。 它返回用于该会话的密钥对;如果没有可用密钥,则返回 null。
  1. algorithm list 为空列表

  2. 对每个 algorithm,该项在 registration entry 中:

    1. 如果 algorithm 不是 sf-token继续

    2. 如果 algorithm 表示一个在 `Secure-Session-Registration` 中受支持的加密算法,并且此客户端支持它, 将 algorithm 添加到 algorithm list

  3. 如果 algorithm list 为空,返回 null。

  4. 如果 params["provider_key"]、params["provider_id"] 或 params["provider_url"] 中任一个存在:

    1. 如果三个键中有任意一个缺失,返回 null。

    2. permission 为对 "device-bound-session-key-sharing" 执行请求使用权限的结果。

    3. 如果 permission"denied", 返回 null。

    4. provider URL 为从 params["provider_url"] 构造的URL

    5. provider originprovider URLorigin

    6. 如果 provider origin 为不透明,返回 null。

    7. provider domainprovider URLhost可注册域

    8. provider identifierparams["provider_id"]。

    9. provider session 为用户代理的 会话 存储[provider domain][provider identifier] 中的会话。

    10. 如果 provider session 为 null,返回 null。

    11. 如果 provider session会话范围originprovider origin 不是同源,返回 null。

    12. 如果 provider session会话密钥对的 JWK thumbprint(参见 [RFC7638])在用 base64 编码时(参见 [RFC4648])不匹配 params["provider_key"], 返回 null。

    13. provider well known URLprovider URL 的副本,将 path 替换为 "/.well-known/device-bound-sessions"。

    14. provider well known response 为 fetch provider well known URL 的结果。如果满足以下任一条件,返回 null:

      1. provider well known responsestatus 不是 200。

      2. provider well known responsebody 不是 JSON 编码的 字典。

      3. provider well known responsebody 包含键 "provider_origin"。

      4. provider well known responsebody 未包含 键 "relying_origins"。

      5. 键 "relying_origins" 的值不包含 registration URLorigin

    15. 用户代理 SHOULD 对 "relying_origins" 中可注册来源标签的数量设置上限,以防止 滥用。

    16. relying well known URLregistration URL 的副本,将 path 替换为 "/.well-known/device-bound-sessions"。

    17. relying well known response 为 fetch relying well known URL 的结果。如果满足以下任一条件,返回 null:

      1. relying well known responsestatus 不是 200。

      2. relying well known responsebody 不是 JSON 编码的 字典。

      3. relying well known responsebody 包含键 "relying_origins"。

      4. relying well known responsebody 未包含 键 "provider_origin"。

      5. 键 "provider_origin" 的值不是 provider URLorigin

    18. 返回 provider session会话密钥对

  5. 返回为 algorithm list 创建的新密钥对。

8.12. 添加 debug 标头

为了让站点理解用户代理何时选择不 应用会话,用户代理应向请求request添加 debug 标头,使用一个sf-tokentoken)和一个字符串session id)。
  1. value 为一个sf-token, 其值为 token

  2. value 上的sf-parameter "session_identifier" 设为 session id

  3. skipped header value 为在 requestheader list上,使用header name "Secure-Session-Skipped"、类型 "list" 运行获取结构化字段值 的步骤所得的结果。

  4. 如果 skipped header value 为 null,将其设为空sf-list

  5. value 追加到 skipped header value

  6. requestheader list上,给定 ("Secure-Session-Skipped", skipped header value),运行设置结构化字段值 的步骤。

9. DBSC 格式

9.1. `Secure-Session-Registration` HTTP 标头字段

Secure-Session-Registration 标头字段可由服务器在 响应中使用,以在客户端上启动一个新的设备绑定会话

`Secure-Session-Registration` 是一个 List Structured Header [RFC9651]。其 ABNF 为:

SecureSessionRegistration = sf-list

列表中的每一项都必须是一个 inner list,且 inner list 中的每一项 MUST 是表示受支持算法(ES256、RS256)的sf-token。 当前仅支持这两个值。

定义了以下 sf-parameter

来自 https://example.com/login.html 的 `Secure-Session-Registration` 的一些示例:
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256 RS256);path="reg";challenge="cv"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a"
Secure-Session-Registration: (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a", (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";provider_key="abc";provider_id="idp_id";provider_url="https://id_origin.example.com"

9.2. `Secure-Session-Challenge` HTTP 标头字段

Secure-Session-Challenge 标头字段可由服务器在 响应中使用,以向客户端发送 challenge,服务器期望该 challenge 在未来 `Secure-Session-Response` 标头内的DBSC 证明中使用, 或者在 cookie 刷新期间 如果status 为 403,则立即请求新签名的DBSC 证明

`Secure-Session-Challenge` 是一个 structured header。其值必须是字符串。 其 ABNF 为:

SecureSessionChallenge = sf-string
该项的语义定义在 § 9.2.1 `Secure-Session-Challenge` 结构化标头 序列化中。

处理步骤定义在 § 8.7 缓存 challenge 中。

9.2.1. `Secure-Session-Challenge` 结构化标头序列化

`Secure-Session-Challenge` 表示为 Structured Field。[RFC9651]

在此表示中,challenge 表示为字符串。

Challenge MUST 具有一个名为 "id"sf-parameter,其值 MUST 是一个表示会话标识符的字符串。任何其他 sf-parameter SHOULD 被忽略。

来自 https://example.com/login.html 的 `Secure-Session-Challenge` 的一些示例:
HTTP/1.1 403 Forbidden
Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK
Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK
Secure-Session-Challenge: "new challenge";id="my session 1"
Secure-Session-Challenge: "another challenge";id="my session 2"
HTTP/1.1 200 OK
Secure-Session-Challenge: "c1";id="session 1", "c2";id="session 2"

9.3. `Secure-Session-Response` HTTP 标头字段

Secure-Session-Response 标头字段可由用户代理在 请求中使用,以向服务器发送DBSC 证明,证明 客户端仍持有会话密钥对的私钥。

Secure-Session-Response 是一个 structured header。其值必须是字符串。其 ABNF 为:

SecureSessionResponse = sf-string

此字符串 MUST 只包含DBSC 证明 JWT。任何sf-parameter SHOULD 被 忽略。

POST example.com/refresh
Secure-Session-Response: "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRic2Mrand0In0.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL3JlZyIsImp0aSI6ImN2IiwiaWF0IjoiMTcyNTU3OTA1NSIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZfR0Iydm9RMHFyb01oNk9sREZDRlNfU0pyaVFpMVBUdnZCT2hHWjNiSEkiLCJ5IjoiSWVnT0pVTHlFN1N4SF9DZDFLQ0VSN2xXQnZHRkhRLWgweHlqelVqRUlXRSJ9LCJhdXRob3JpemF0aW9uIjoiYWMifQ.6Fb_vVBDmfNghQiBmIGe8o7tBfYPbPCywhQruP0vIhxgmcJmuNTaMHeVn_M8ZnOm1_bzIitbZqCWEn-1Qzmtyw"

9.4. `Sec-Secure-Session-Id` HTTP 标头字段

Sec-Secure-Session-Id 标头字段可由用户代理在 请求中使用,以请求刷新当前会话, 并将当前会话标识符作为字符串参数。

`Sec-Secure-Session-Id` 是一个 structured header。 其值必须是字符串。其 ABNF 为:

SecSecureSessionId = sf-string

此字符串 MUST 只包含会话标识符。任何参数 SHOULD 被 忽略。

POST example.com/refresh
Sec-Secure-Session-Id: "session-id"

9.5. `Secure-Session-Skipped` HTTP 标头字段

Secure-Session-Skipped 标头字段可在 请求中使用,以指示该请求因用户代理策略而有意缺少绑定 凭据。

`Secure-Session-Skipped` 是一个 List Structured Header [RFC9651]。其 ABNF 为:

SecureSessionSkipped = sf-list

列表中的每一项 MUST 是一个表示 跳过 cookie 刷新的粗粒度原因的sf-token。 唯一受支持的值是:"unreachable"、"server_error" 和 "quota_exceeded"。这些 token 应在以下情况下使用:

定义了一个 sf-parameter

GET example.com/requires_bound_cookie
Secure-Session-Skipped: unreachable;session_identifier=123, quota_exceeded;session_identifier=456

9.6. JSON 会话指令格式

服务器在会话注册期间发送JSON 会话指令,并可选地在会话刷新期间发送。如果响应 包含会话指令,它 MUST 为 JSON 格式。

在 JSON 对象根部,可以存在以下键:

session_identifier

一个字符串,表示会话标识符。 注册期间,这是新创建 会话的标识符。此键 MUST 存在,除非 continue 键的值为 false。刷新期间,这 MUST 是当前 会话的标识符。见 § 8.9 创建会话

refresh_url

一个字符串,表示用于未来刷新请求的 URL。 它可以是完整的 URL,也可以相对于提供这些指令的 请求。 此键是 OPTIONAL;如果不存在,将使用该请求url 作为未来刷新请求。

continue

一个布尔值,指示会话是否应继续适用。 注册和刷新端点可以将此设为 false 以终止会话。 此键是 OPTIONAL;如果不存在,默认值将为 true。

scope

一个JSON 会话 范围,描述该 会话覆盖的资源。此键 MUST 存在,除非 continue 键的值为 false。

credentials

一个列表,包含 JSON 会话凭据,描述此会话保护的 cookie。此键 MUST 存在,除非 continue 键的值为 false。

allowed_refresh_initiators

一个列表,包含 描述哪些主机允许发起 DBSC 刷新的字符串。详见 § 8.3 识别请求是否允许 刷新。此键 是 OPTIONAL;如果不存在,默认值将为空列表。

{
  "session_identifier": "session_id",
  "refresh_url": "/RefreshEndpoint",

  "continue": false,

  "scope": {
    // 默认按来源定范围(即 https://example.com)
    "origin": "https://example.com",
    // 指定包含 https://*.example.com,但排除的子域除外。
    // 只有当来源的主机是根 eTLD+1 时,这才能为 true。
    "include_site": true,

    "scope_specification" : [
      { "type": "include", "domain": "trusted.example.com", "path": "/only_trusted_path" },
      { "type": "exclude", "domain": "untrusted.example.com", "path": "/" },
      { "type": "exclude", "domain": "*.example.com", "path": "/static" }
    ]
  },

  "credentials": [{
    "type": "cookie",
    // 这指定此配置适用的确切 cookie。属性
    // 匹配 RFC 6265bis 中的 cookie 属性,并以类似于
    // 普通 Set-Cookie 行的方式解析,使用相同默认值。
    // 这些 SHOULD 等同于伴随此 
    // 响应的 Set-Cookie 行。
    "name": "auth_cookie",
    "attributes": "Domain=example.com; Path=/; Secure; HttpOnly; SameSite=None"
    // 属性 Max-Age 和 Expires 会被忽略
  }],
    
  "allowed_refresh_initiators": [
    "example.com", 
    "*.example.com",
    "site-embedding-example.com"
  ]
}

9.7. JSON 会话范围指令格式

服务器在注册期间的JSON 会话指令中发送一个JSON 会话范围,并可选地在 会话刷新期间发送。

在 JSON 对象根部,可以存在以下键:

origin

一个字符串,指示会话适用的来源或站点。 此键是 OPTIONAL;如果不存在,将使用提供 指令的 URL 的来源。注册期间这是注册 URL, 刷新期间这是刷新 URL。

include_site

一个布尔值,指示会话是按来源定范围(false)还是 按站点定范围(true)。此键 MUST 存在。请注意,这优先于 "scope_specification" 中的任何JSON 会话范围规则 (见 § 8.2 识别 URL 是否在会话范围内)。

scope_specification

一个列表,包含 JSON 会话范围规则,描述对 默认范围(整个来源或站点)的修改。此键是 OPTIONAL;如果 不存在,将使用空列表。

9.8. JSON 会话范围规则格式

服务器在注册期间的 JSON 会话范围 中发送一个JSON 会话范围规则对象列表,并可选地在会话 刷新期间发送。

在每个JSON 会话范围规则的根部,可以存在以下键:

type

一个字符串,指示该规则包含还是排除目标。 此键 MUST 存在,且值 MUST 是 "include" 或 "exclude"。

domain

一个字符串,指示应与规则匹配的域名。这可以 包含通配符(见 § 8.2 识别 URL 是否在 会话范围内)。此键是 OPTIONAL;如果 不存在,它将为 '*',匹配所有域名。

path

一个字符串,指示应与规则匹配的路径前缀。此 键是 OPTIONAL;如果不存在,它将为 '/',匹配所有路径。详细 语义见 § 8.2 识别 URL 是否在会话范围内

9.9. JSON 会话凭据格式

服务器在注册期间的 JSON 会话 指令中发送一个JSON 会话凭据对象列表,并可选地在会话 刷新期间发送。

在 JSON 对象根部,可以存在以下键:

type

一个字符串,指示此会话保护的凭据种类。 此键 MUST 存在,且值 MUST 是 "cookie"。

name

一个字符串,指示绑定 cookie 的名称。

attributes

一个字符串,包含受保护 cookie 的预期属性。 详见 § 8.6 识别是否缺少会话 凭据 中关于此内容如何 使用的说明。

9.10. DBSC 证明 JWT 语法

DBSC 证明是一个 JWT proof,它由客户端选择的私钥签名(使用 JSON Web Signature (JWS))。

DBSC 证明的标头 MUST 至少包含以下sf-parameter

typ

一个字符串。这 MUST 是 "dbsc+jwt"。

alg

一个字符串,定义用于签署此 JWT 的算法。它 MUST 是 [IANA.JOSE.ALGS] 中的 "RS256" 或 "ES256"。

DBSC 证明的载荷 MUST 至少包含以下声明:

aud

一个字符串。这 MUST 是此 JWT 最初发送到的 URL。 示例:"https://example.com/refresh.html"。

jti

一个字符串。这是注册 标头中发送的 challenge 值的副本。

iat

一个 double,用于标识 JWT 签发的时间。它可用于 确定 JWT 的年龄。其值 MUST 是一个包含 NumericDate 值的数字, 如 [RFC7519] 所述。

key

一个字典,定义 [RFC7517] 中指定的 JWK。

此外,如果以下声明出现在 `Secure-Session-Registration` 标头字段中,则 MUST 存在:

authorization

一个字符串。这是直接复制自 `Secure-Session-Registration` 标头字段(如果在那里设置)的字符串。请注意,此 字符串在标头中是 OPTIONAL,但如果它存在, 客户端 MUST 将其添加到DBSC 证明中的声明。

如果 DBSC 证明用于刷新请求,则以下声明 MUST 存在:

sub

一个字符串,指定会话标识符

发送到 https://example.com/reg 的DBSC 证明示例:
// 标头
{
  "alg": "ES256",
  "typ": "dbsc+jwt"
}
// 载荷
{
  "aud": "https://example.com/reg",
  "jti": "cv",
  "iat": 1725579055.0,
  "key": {
    "kty": "EC",
    "crv": "P-256",
    "x": "6_GB2voQ0qroMh6OlDFCFS_SJriQi1PTvvBOhGZ3bHI",
    "y": "IegOJULyE7SxH_Cd1KCER7lWBvGFHQ-h0xyjzUjEIWE"
  },
  "authorization": "ac"
}

基于对 http://example.com/page.html 的响应,该响应具有来自服务器的此 响应标头:

HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"

10. 对其他规范的更改

10.1. 对 Fetch 规范的更改

本规范要求更新 HTTP-network-or-cache fetch 算法。请求具有延迟的设备 绑定会话 ids,这是一个列表,包含由以下内容组成的元组

此列表初始为空。

在步骤 8.21 中计算 cookie 后,运行 § 8.5 识别需要刷新的会话。如果得到的 session 非 null:

  1. 使用 httpRequest、返回的 session会话密钥对刷新 URL会话标识符已缓存 challenge,以及空 authorization 运行 § 8.8 发送请求

  2. 使用原始输入重新启动 HTTP-network-or-cache fetch

本规范还要求进行两次新的调用以处理新的 标头。在当前 HTTP-network fetch 的步骤 14 之后,执行以下步骤:

  1. 运行 § 8.10 处理会话注册§ 8.7 缓存 challenge

10.2. 对 Clear Site Data 规范的更改

本规范要求 Clear Site Data 规范第 4.2.5 节 Clear DOM-accessible storage for origin 清除其范围匹配 origin 的所有设备绑定会话。它还要求更新第 4.2.4 节,以 清除与注册域匹配的站点的设备绑定会话。

11. IANA 考量

永久消息标头字段注册表应更新为包含以下 注册项:[RFC3864]

11.1. Secure-Session-Challenge

标头字段名称
Secure-Session-Challenge
适用协议
http
状态
draft
作者/变更控制者
W3C
规范文档
本规范(见 § 9.2 `Secure-Session-Challenge` HTTP 标头字段

11.2. Sec-Secure-Session-Id

标头字段名称
Sec-Secure-Session-Id
适用协议
http
状态
draft
作者/变更控制者
W3C
规范文档
本规范(见 § 9.4 `Sec-Secure-Session-Id` HTTP 标头字段

11.3. Secure-Session-Registration

标头字段名称
Secure-Session-Registration
适用协议
http
状态
draft
作者/变更控制者
W3C
规范文档
本规范(见 § 9.1 `Secure-Session-Registration` HTTP 标头字段

11.4. Secure-Session-Response

标头字段名称
Secure-Session-Response
适用协议
http
状态
draft
作者/变更控制者
W3C
规范文档
本规范(见 § 9.3 `Secure-Session-Response` HTTP 标头字段

11.5. Secure-Session-Skipped

标头字段名称
Secure-Session-Skipped
适用协议
http
状态
draft
作者/变更控制者
W3C
规范文档
本规范(见 § 9.5 `Secure-Session-Skipped` HTTP 标头字段

11.6. device-bound-sessions Well Known

Well-Known URI 注册表应更新为包含 /.well-known/device-bound-sessions。

此端点必须提供一个 JSON 编码的字典。定义了三个键:

如果 https://example.com/.well-known/device-bound-sessions 提供
{
  "registering_origins": [
    "https://subdomain.example.com",
    "https://subdomain.example.com:8000",
  ],
  "relying_origins": [
    "https://example.co.uk",
    "https://example-partner.com",
  ],
}

则只有在以下任一条件为 true 时,注册请求才能定义 站点范围的会话:

此外,https://example.co.ukhttps://example-partner.com 被允许与 https://example.com 上的会话共享密钥, 从而使这些站点能够同时实现联合登录和 DBSC 保护。为此,这两个站点都必须在其 .well-known 文件中提供以下条目:

{
  "provider_origin": "https://example.com/"
}

12. 变更日志

这是该规范的早期草案。

13. 致谢

一致性

文档 约定

一致性要求通过 描述性断言 与 RFC 2119 术语的组合来表达。 本文档规范性部分中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、 “MAY” 和 “OPTIONAL” 应按 RFC 2119 中所述解释。 然而,为了可读性, 这些词在本规范中并不总是以全大写字母出现。

本规范的全部文本均为规范性内容, 但明确标记为非规范性的章节、示例和注释除外。[RFC2119]

本规范中的示例会以 “for example” 这样的词引入, 或者使用 class="example" 与规范性文本区分开来, 如下所示:

这是一个资料性示例的例子。

资料性注释以 “Note” 一词开头, 并使用 class="note" 与规范性文本区分开来, 如下所示:

Note,这是一个资料性注释。

一致性 算法

作为算法一部分而以祈使语气表述的要求 (例如 "strip any leading space characters" 或 "return false and abort these steps") 应按引入该算法时所使用的关键词 ("must"、"should"、"may" 等) 的含义解释。

以算法或特定步骤表述的一致性要求 可以以任何方式实现, 只要最终结果等价即可。 特别是,本规范中定义的算法 旨在便于理解, 并非旨在高性能。 鼓励实现者进行优化。

索引

由本 规范定义的术语

由 引用定义的术语

参考文献

规范性参考文献

[COOKIES]
A. Barth. HTTP 状态管理机制. 2011年4月。拟议标准。URL: https://httpwg.org/specs/rfc6265.html
[FETCH]
Anne van Kesteren. Fetch 现行标准. 现行标准。URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. 高分辨率时间. 2024年11月7日。 WD。URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 现行标准. 现行标准。URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 现行标准. 现行标准。URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2025年6月24日。 WD。URL: https://www.w3.org/TR/permissions/
[RFC2119]
S. Bradner. RFC 中用于 表示要求级别的关键词. 1997年3月。最佳当前实践。URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul. 消息标头字段的 注册程序. 2004年9月。最佳当前实践。URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC4648]
S. Josefsson. Base16、Base32 和 Base64 数据 编码. 2006年10月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell. 语法 规范的扩充 BNF:ABNF. 2008年1月。互联网标准。URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7405]
P. Kyzivat. ABNF 中的大小写敏感字符串 支持. 2014年12月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7405
[RFC7517]
M. Jones. JSON Web Key (JWK). 2015年5月。 拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7517
[RFC7519]
M. Jones; J. Bradley; N. Sakimura. JSON Web Token (JWT). 2015年5月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7519
[RFC7638]
M. Jones; N. Sakimura. JSON Web Key (JWK) Thumbprint. 2015年9月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc7638
[RFC9112]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP/1.1. 2022年6月。互联网标准。 URL: https://httpwg.org/specs/rfc9112.html
[RFC9651]
M. Nottingham; P-H. Kamp. HTTP 的结构化字段值. 2024年9月。拟议标准。URL: https://www.rfc-editor.org/rfc/rfc9651
[URL]
Anne van Kesteren. URL 现行标准. 现行标准。 URL: https://url.spec.whatwg.org/