链接式 Web 存储协议 1.0

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-lws10-core-20260622/
最新发布版本:
https://www.w3.org/TR/lws10-core/
最新编辑草案:
https://w3c.github.io/lws-protocol/lws10-core/
历史:
https://www.w3.org/standards/history/lws10-core/
提交历史
编辑:
Jesse Wright牛津大学
Erich Bremer石溪大学
反馈:
GitHub w3c/lws-protocol拉取请求新建议题开放议题

摘要

Linked Web Storage Protocol 规范旨在以互操作的方式,为应用程序提供对外部存储数据的安全且经许可的访问。

本文档状态

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

这是一项非官方提案。

本文档由 Linked Web Storage 工作 组作为 工作草案发布,并使用 推荐标准 轨道

作为 工作草案发布并不意味着 W3C 及其成员认可该文档。

这是一份草案文档,可能随时被其他文档更新、替换或废弃。 除了作为正在进行中的工作外,不宜引用本文档。

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

本文档受 2025年8月18日 W3C 流程文档管辖。

1. 文档约定

本节为非规范性内容。

2. 引言

2.1 资源访问

LWS 协议定义了标准交互,某一方可通过这些交互向某些 代理提供某些资源。

2.2 安全和隐私

资源管理者可以将被服务资源 保持为私有,可以使其对任何人公开可用,或者可以将其可见性限制到一组受约束的 请求代理

2.3 一致性

除标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。 本规范中的其他所有内容均为规范性内容。

本文档中的关键词 MAYMUSTMUST NOTOPTIONALRECOMMENDEDREQUIREDSHOULDSHOULD NOT 应按 BCP 14 [RFC2119] [RFC8174] 中的描述解释,且仅当它们像这里所示以全 大写形式出现时才如此解释。

LWS 服务器是一个 HTTP 服务器 [rfc9112],它遵守 本规范中所有相关的“MUST”陈述。具体而言, 必须遵守本文档9. 操作中的相关规范性“MUST”陈述。

LWS 客户端是一个 HTTP 客户端 [rfc9112],它遵守本规范中所有相关的“MUST”陈述。具体而言,必须遵守本文档9. 操作中的相关规范性 “MUST”陈述。

3. 术语

术语“authorization server”和“client”由 OAuth 2.0 Authorization Framework [RFC6749] 定义。

术语“end-user”和“issuer”由 OpenID Connect Core 1.0 [OPENID-CONNECT-CORE] 定义。

本规范定义以下术语:

(有风险特性)议题: 本节可能会被移除

本规范定义了对被服务 资源执行的操作、由此产生的状态变化,以及一个响应,该响应旨在向请求代理提供所请求的信息,或告知其 操作的结果。 操作是可对 被服务资源执行的以下任何动作:

  • 创建资源 -
  • 读取 资源 -
  • 更新 资源 -
  • 删除 资源 -

以下章节将描述这些操作的语义和响应,但 以下核心 响应适用于任何操作:

  • 成功 - 该操作被认为已经完成。这可能伴随一个资源表示,用于传达被服务资源的内容。对于创建资源操作,不定义成功响应。 请改见已创建
  • 不 允许
  • 未知 请求者
  • 未知 错误 - 保留用于规范未预见到的错误条件

4. 身份验证

本节定义了一种机制,用于标识与链接式 Web 存储服务器交互的代理和最终用户。 本规范并不强制要求身份验证凭证采用特定 格式,但它确实描述了如何将现有身份系统 与链接式 Web 存储授权框架结合使用。

4.1 身份验证 凭证数据模型

本节描述的数据模型概述了身份验证凭证的任何 具体序列化所需满足的要求。

身份验证凭证MUST 包含关于主体的防篡改声明,包括:

4.2 身份验证 凭证验证

身份验证凭证的验证需要凭证的 验证者和颁发者之间存在信任关系。此信任关系MAY 通过 带外机制建立。用于在验证者和颁发者之间建立信任的任何其他机制 均在特定的身份验证套件中概述。

身份验证凭证MUST 被签名。RECOMMENDED 使用非对称密码学 进行签名。

4.3 身份验证 凭证类型标识符

每个身份验证套件MUST 关联一个令牌类型 URI。身份验证套件SHOULD 使用 IANA “OAuth URI”注册表中定义的 URI。

5. 授权

Linked Web Storage 描述了一种在 Web 上持久化和管理受保护数据的机制。 授权是这样一种机制: 代理 通过它请求并呈现访问令牌,以访问这些受保护数据。

本节定义了一个基于 OAuth 2.0 [RFC6749] 的授权框架,作为 获取和呈现 访问令牌的基线机制。服务器MAY 支持此 基线之外的其他授权机制。

5.1 角色

LWS 授权中的角色与 OAuth 2.0 第 1.1 节 [RFC6749] 中定义的角色相同: 资源所有者资源服务器、 客户端(在本规范中称为授权客户端,以 避免歧义),以及 授权服务器。 存储服务器是一种资源服务器,同时也符合 LWS 存储规范。

5.2 协议流程

本规范描述了客户端与授权服务器之间的交互,以及 客户端与合规存储服务器之间的交互。

授权服务器与存储服务器之间的交互不在本 规范范围内。 授权服务器可以与存储服务器是同一服务器,也可以是单独的实体。

5.2.1 授权服务器 发现

由存储服务器管理的所有受保护资源都需要由受信任 授权服务器生成的有效访问令牌。客户端可以通过向受保护资源发出 未授权的 HTTP 请求来发现受信任授权服务器的位置。

生成 401(未授权)响应的存储服务器MUST 发送一个 WWW-Authenticate 标头 字段,其中至少包含一个合规质询。合规质询将包含 下述参数:

  • as_uri REQUIRED — 此 参数的值是一个 URI,用于标识授权服务器, 客户端可在该授权服务器处获取访问令牌。此参数的值将与 有效访问令牌的 iss 声明相同。
  • realm REQUIRED — 此 参数的值是一个 URI,表示保护范围。 此值将包含在访问令牌的 audience(aud)声明中。 客户端MUST 验证 发起请求的 URI 在逻辑上包含于此响应中呈现的 realm 之内。

可以包含其他标头和参数。

下面包含一个 401 响应示例。

HTTP/2 401 Unauthorized
Link: <https://storage.example/storage_1/metadata>; rel="storageDescription"
WWW-Authenticate: Bearer as_uri="https://authorization.example",
                realm="https://storage.example/storage_1",
                error="invalid_token"

5.2.2 授权服务器 元数据

授权服务器MUST 提供一个元数据资源,以允许客户端 按照 [RFC8414] 中的描述 发现端点位置和能力。此元数据资源 MUST 可在路径为 /.well-known/lws-configuration 的 URL 处获得。

授权服务器SHOULD 通过在服务器元数据文档中包含 subject_token_types_supported 条目,宣告其支持的主体令牌。此条目是一个 JSON 数组,其中包含可在 授权服务器令牌端点提供的有效 subject_token_type 值列表。

下面包含一个授权服务器元数据资源示例。

{
    "issuer": "https://authorization.example",
    "grant_types_supported": [
        "urn:ietf:params:oauth:grant-type:token-exchange"],
    "token_endpoint": "https://authorization.example/token",
    "jwks_uri": "https://authorization.example/jwks",
    "claims_supported": [
        "sub",
        "iss",
        "client_id",
        "aud"],
    "response_types_supported": [
        "token"],
    "subject_token_types_supported": [
        "urn:ietf:params:oauth:token-type:jwt",
        "urn:ietf:params:oauth:token-type:id-token"]
}

5.2.3 令牌交换

LWS 授权服务器是一个合规的 OAuth 2.0 授权服务器,能够向客户端颁发 访问令牌, 以供存储服务器使用。为了颁发访问令牌,客户端必须首先通过 OAuth 2.0 Token Exchange [RFC8693] 向授权服务器呈现有效的主体令牌, 例如身份验证凭证

5.2.3.1 请求

授权服务器的令牌端点MUST 支持 urn:ietf:params:oauth:grant-type:token-exchange 授权类型,如 OAuth 2.0 Token Exchange [RFC8693] 中所述。

执行令牌交换授权类型时,适用以下附加要求:

  • resource 参数是REQUIRED。此 参数的值MUST 是 URI,并将用于填充所得访问令牌中的 aud(受众)声明。提供的值将与 WWW-Authenticate 质询中的 realm 参数响应相同。授权服务器 MUST 拒绝任何 resource 参数标识 未知或不受信任存储的请求。
  • subject_token 参数是REQUIRED。此 参数的值MUST 包含有效的主体令牌, 例如身份验证 凭证
  • 在向客户端返回访问令牌之前,授权服务器MUST 成功验证所有呈现的令牌。

令牌请求的非规范性示例(subject_token 参数已被 截断)。

POST /token HTTP/1.1
Host: authorization.example
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fstorage.example%2Fstorage_1
&subject_token=eyJ0eXAiOiJhcytqd3QiLCJhbGciO...fiK51VwhsxJ-siBMR-YFiA
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
5.2.3.2 响应

如果令牌请求有效且客户端被授权发出该请求,则 授权服务器响应MUST 符合 OAuth 2.0 Authorization Framework [RFC6749] 第 5.1 节。所得访问 令牌MUST 符合 JSON Web Token Profile for OAuth 2.0 Access Tokens [RFC9068]。

此外,访问令牌必须满足以下要求:

  • sub(主体)— REQUIRED。此声明 MUST 是标识执行 操作的代理的 URI
  • iss(颁发者)— REQUIRED。此声明 MUST 是授权服务器的 URI
  • client_id(客户端 id)— REQUIRED。 此声明MUST 是标识客户端的 URI。
  • aud(受众)— REQUIRED。此声明 MUST 包含客户端 在 resource 参数中提供的 URI。此值将用于限制访问令牌对哪些实体 有效。它将 与存储服务器在 WWW-Authenticate 质询的 realm 参数中提供的值 相同。
  • exp(过期时间)— REQUIRED。 授权服务器SHOULD 颁发短生命周期的令牌 (RECOMMENDED:300 秒或更短),以限制令牌 被盗造成的暴露。
  • iat(签发时间)— REQUIRED
  • jti(JWT ID)— REQUIRED

下面包含一个成功令牌响应的非规范性示例。

HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token":"eyJ0eXAiOiJhcytqd3QiLCJhbGciOiJFUzI1NiIs...DeWt4QuZXso",
    "token_type":"Bearer",
    "expires_in":3600
}

所有无效或未授权的请求MUST 产生错误响应, 如 OAuth 2.0 Authorization Framework [RFC6749] 第 5.2 节中所述。

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "error":"invalid_request"
}
5.2.3.3 访问令牌示例

本节为非规范性内容。

下面包含一个由授权服务器颁发的访问令牌示例。

{
  "kid": "ec51c6b2",
  "kty": "EC",
  "alg": "ES256",
  "crv": "P-256",
  "typ": "at+jwt"
}
.
{
  "sub": "https://id.example/agent",
  "iss": "https://authorization.example",
  "client_id": "https://app.example/id",
  "aud": "https://storage.example",
  "exp": 1735686300,
  "iat": 1735686000,
  "jti": "550e8400-e29b-41d4-a716-446655440000"
}
.
signature

5.2.4 存储服务器进行的令牌验证

一旦客户端拥有访问令牌,它就会将此令牌呈现给存储服务器。 存储服务器负责在执行任何操作之前验证此令牌。

5.2.4.1 呈现

客户端MUST 使用 Authorization 标头 以及 [RFC6750] 中定义的身份验证方案, 向存储服务器呈现访问令牌。

Authorization: Bearer eyJ0eXAiOiJhcytqd3QiLCJhbGciOiJFUzI1NiIs...DeWt4QuZXso
5.2.4.2 验证

存储服务器MUST 通过执行 以下检查来验证访问令牌,并在任何检查失败时拒绝请求:

  • JWT 签名验证:使用从授权服务器元数据中指定的 jwks_uri 获取的授权服务器公钥来验证 JWT 签名。存储服务器SHOULD 缓存这些密钥,并且 MUST 支持密钥轮换。
  • 颁发者验证:验证 iss 声明与预期的授权 服务器标识符匹配。
  • 受众验证:验证 aud 声明恰好包含一个值,并且该 值是标识在逻辑上包含目标资源的存储服务器的 URI。
  • 时间验证,受系统之间允许的时钟偏差约束。
    • 验证当前时间早于 exp(过期时间)声明。
    • 如果存在 nbf(不早于)声明,验证当前时间不早于该声明。
    • 验证 iat(签发时间)声明不在未来。

如果验证失败,存储服务器MUST 返回 401 Unauthorized, 并带有 WWW-Authenticate 标头, 其中包含适当的 error 参数(例如 invalid_token、invalid_request 或 insufficient_scope)。

如果令牌在其他方面有效,但授权策略不允许所请求的 操作, 则存储服务器MUST 拒绝该请求。

6. 发现

6.1 存储描述资源

存储描述资源提供 客户端在与存储交互时可使用的信息,包括能力和 服务端点的描述。

6.1.1 数据模型

  • id - id 属性是REQUIRED。其值MUST 是一个 URI,用于 标识存储
  • type - type 属性是REQUIRED。其值MUST 是一个字符串, 等于 Storage,或是一组字符串,其中包含等于 Storage 的项 (区分大小写)。
  • capability - capability 属性是OPTIONAL。其值MUST 是一组 能力,其中每个能力由包含以下属性的映射描述。 可以存在其他属性。
    • id - id 属性是OPTIONAL。如果存在,其值MUST 是一个 URI。
    • type - type 属性是REQUIRED。其值MUST 是字符串 或一组字符串。
  • service - service 属性是REQUIRED。其值MUST 是一组服务, 其中每个服务由包含以下属性的映射描述。可以存在其他 属性。
    • id - id 属性是OPTIONAL。如果存在,其值MUST 是一个 URI。
    • type - type 属性是REQUIRED。其值MUST 是字符串 或一组字符串。
    • serviceEndpoint - serviceEndpoint 属性是REQUIRED。其值MUST 是一个 URI。
示例 8:最小存储描述资源
{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "https://storage.example/",
  "type": "Storage",
  "service": [{
    "type": "StorageDescription",
    "serviceEndpoint": "https://storage.example/description"
  }]
}

6.1.2 发现和绑定

所有针对存储资源的 GETHEAD 请求的响应MUST 包含一个 Link 标头,其目标是存储 描述资源的 URI,并包含一个关系 (rel)参数,其值等于 https://www.w3.org/ns/lws#storageDescription

解引用时,存储描述MUST 包含一个用于标识 存储id 属性。此外,service 属性MUST 包含一个服务描述,其类型等于 StorageDescription,并且其 serviceEndpoint 等于 存储描述的 URL。

存储描述的 URI 可以不同于标识存储的 URI,而后者又可以不同 于存储根。这些 URI 也可以相同,前提是 生成的表示 符合本文档中列出的要求。

6.1.3 存储能力

存储描述可以包含存储所支持的 其他能力的描述。

6.1.4 存储服务

StorageDescription 服务之外,存储描述资源可以包含 指向与存储相关联的其他服务的链接。这些服务的 API 定义不在 本规范范围内。

6.1.5 存储 描述表示

存储描述资源MUST 能够使用媒体类型 application/lws+json 序列化。 其他表示可以通过内容协商提供。

示例 9:存储描述资源
{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "https://storage.example/",
  "type": "Storage",
  "capability": [{
    "type": "https://feature.example/PatchSupport",
    "mediaType": {
      "text/turtle": ["application/sparql-update"],
      "application/n-triples": ["application/sparql-update"],
      "application/linkset+json": ["application/merge-patch+json", "application/json-patch+json"]
    }
  }, {
    "type": "https://feature.example/ResumableUploads"
  }, {
    "type": "https://feature.example/ContentNegotiation",
    "source": "application/ld+json",
    "target": ["text/turtle", "application/n-triples"]
  }, {
    "type": "https://feature.example/ContentNegotiation",
    "source": "image/jpeg",
    "target": ["image/png"]
  }],
  "service": [{
    "type": "NotificationService",
    "serviceEndpoint": "https://storage.example/notification/api",
    "subscriptionType": ["WebhookSubscription"]
  }, {
    "type": "TypeIndexService",
    "serviceEndpoint": "https://storage.example/types/index"
  }, {
    "type": "TypeSearchService",
    "serviceEndpoint": "https://storage.example/types/search"
  }, {
    "type": "DataSharingService",
    "serviceEndpoint": "https://storage.example/sharing/api"
  }, {
    "type": "StorageDescription",
    "serviceEndpoint": "https://storage.example/description"
  }]
}

7. 逻辑资源组织

7.1 容器模型

Linked Web Storage 将资源组织到容器中。容器是一种 专门资源,它保存对其他资源的引用,这些资源称为其成员。容器充当 组织单元,类似于目录或集合,使客户端能够对资源进行分组、发现 和导航。容器维护对其成员资源的引用, 这些成员资源可以同时包括非容器资源和其他容器资源,从而支持 层级结构。通常,容器除了元数据或成员枚举之外, 仅包含最少的内在内容;其主要作用是聚合和结构化 下级资源。存储系统的根被指定为容器,作为 没有上级父项的顶层组织单元。容器MUST 使用 'ContainerPage' 类型支持成员列表的分页,并具有 'first'、 'next'、'prev' 和 'last' 等属性。表示MUST 使用带有特定 框架和规范性上下文的 JSON-LD,并可选择通过 'Vary: Accept' 标头宣告内容协商。 存储MAY 作为根容器运行,从而允许直接写入。

每个 LWS 存储都有一个存储 根,作为顶级组织单元。存储根没有父项,并充当 存储 层级的入口点。

LWS 中的资源被分类为以下两类之一:

7.2 包含关系

资源与其父容器之间的包含关系通过 rel="up" 链接 关系表示。对于任何 非根资源上的 GET 和 HEAD 请求,服务器MUST 在响应中包含一个 Link 标头,其中 rel="up" 指向父容器。

Link: </alice/notes/>; rel="up"

容器的成员在其表示中使用 items 属性列出。服务器管理此列表;客户端不能直接修改它。成员关系 变更作为资源创建和删除的副作用发生。

7.3 包含关系完整性

服务器MUST 始终维护包含关系完整性:

7.4 资源标识

资源由 URI 标识。资源的 URI 独立于其在包含关系层级中的位置。服务器在资源 创建期间分配 URI,并且MAY 纳入客户端提示(例如 Slug 标头), 但客户端SHOULD NOT 假定 URI 结构反映包含关系。

包含关系通过元数据表示 (rel="up" 链接和容器 表示中的 items 属性),而不是通过 URI 路径结构表示。这种分离允许服务器在 URI 分配方面具有灵活性,同时维护一个定义良好的组织模型。

7.5 容器成员关系 和授权

如果客户端对容器具有读取访问权限,则容器 表示MUST 包含该容器中客户端有权访问的所有资源的标识符。它MAY 也包含该容器中客户端无权访问的资源的标识符。

客户端读取容器列表的能力,并不意味着其可访问所包含的 资源本身,反之亦然。

8. 容器

8.1 容器表示

当客户端检索容器时,服务器返回一个结构化的容器 表示,用于描述该容器及其内容。本节 定义容器表示的必需属性和可选属性。

8.1.1 容器属性

容器表示MUST 包含以下属性:

  • id容器的 URI。
  • type:值为 "Container"
  • totalItems:一个整数,表示 容器中可向客户端披露的资源总数。此 计数SHOULD 准确,但MAY 是 近似值。
  • items:被包含资源描述的数组(见下文)。如果 容器为空,则此项MUST 是 空数组。当容器列表 分页时,items 仅包含当前页的资源;详情见分页

8.1.2 被包含资源 描述

items 数组中的每个条目描述容器中包含的一个资源。被包含资源描述MUST 包含:

  • id:被包含资源的 URI。
  • type:资源的类型。MUST"DataResource""Container",或是至少包含 这两个字符串之一的数组。服务器MAY 包含其他用户定义类型作为 URI(例如 ["DataResource", "http://example.org/customType"])。

被包含资源描述SHOULD 包含:

  • mediaType:资源的媒体类型(例如 "text/plain""image/jpeg")。对于 DataResources, MUST 存在此项。
  • size:资源的大小,以字节为单位,以整数表示。
  • modified:资源最后修改的日期和时间, 表示为 ISO 8601 日期时间字符串。

8.1.3 容器 表示示例

以下示例显示位于 /alice/notes/ 的一个容器,其中包含两个 资源:

{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "/alice/notes/",
  "type": "Container",
  "totalItems": 2,
  "items": [
    {
      "type": "DataResource",
      "id": "/alice/notes/shoppinglist.txt",
      "mediaType": "text/plain",
      "size": 47,
      "modified": "2025-11-24T12:00:00Z"
    },
    {
      "type": ["DataResource", "http://example.org/customType"],
      "id": "/alice/notes/todo.json",
      "mediaType": "application/json",
      "size": 2048,
      "modified": "2025-11-24T13:00:00Z"
    }
  ]
}

9. 操作

本节定义 Linked Web Storage(LWS)服务器MUST 支持的四种核心操作。这些操作以 传输无关的方式操纵资源和容器,侧重于语义而不是实现细节。每个操作 都指定输入、预期行为和可能的响应。响应包括成功指示符、资源 表示(在适用时)和错误条件。实现MUST 以原子且一致的方式处理这些操作,这意味着每个操作要么完全成功,要么 失败且没有部分副作用。发生错误时,响应SHOULD 提供 足够细节,使代理能够理解问题,同时不泄露敏感信息。

对于每个核心操作(创建、读取、更新、删除),我们描述要使用的 HTTP 方法、所需 标头或特殊考量(包括通过 ETag 进行并发控制、内容协商,以及 容器列表的分页),以及服务器应执行和返回的内容。标准 HTTP 状态码 用于指示结果,并为诸如配额超出(507 Insufficient Storage)或前提条件失败(412 Precondition Failed)等场景提供额外映射。 该绑定尝试遵循 HTTP/1.1 和 相关 RFC(例如 [RFC7231] 用于 HTTP 语义,[RFC7233] 用于范围 请求,[RFC5789] 用于 PATCH,[RFC8288] 用于 Web Linking, 以及 [RFC9264] 用于 Link Sets),以便它自然地与 Web 标准集成。可发现性通过 诸如 401 响应上的 Link 标头和 WWW-Authenticate 标头等机制得到强调, 避免硬编码 URI 位置。各操作都要求元数据 集成,确保原子性,并使用 Link Sets 表示服务器管理和 用户管理的属性。

注:与本规范中的所有示例一样,本节给出的示例(HTTP 请求 和响应片段)均为非规范性,旨在说明典型用法。实际 要求在描述性文本和表格中陈述。此外,虽然此绑定涵盖 HTTP(作为 初始目标协议),但 LWS 操作原则上将来可以绑定到其他协议。 服务器MUST容器表示 支持 application/lws+jsonapplication/ld+jsonapplication/json 的内容协商 (见11. LWS 媒体类型)。服务器MAY 另外支持 Turtle 等格式。

9.1 元数据

本节定义将元数据与LWS 资源相关联的模型。 LWS 元数据系统基于 Web Linking [RFC8288] 的原则,它 允许服务器使用带类型的链接描述资源之间的关系。元数据增强 可发现性,支持自描述 API,并与资源操作以及容器层级保持一致。

元数据模型 LWS 中的所有元数据都表示为一组源自某个资源(链接上下文)的带类型链接。 每个链接由以下部分组成:

元数据区分资源及其表示,从而在适用时允许多种媒体类型。 对于数据资源,元数据包括表示,每个表示都有 mediaType 和可选的 sizeInBytes。对于容器数据资源,我们 将指向其父容器资源的链接视为该资源元数据的一部分。

Linkset 资源 对于存储中的每个资源,服务器MUST 按照 [RFC9264] 将元数据链接 作为独立资源提供。

发现元数据 客户端主要通过 GET 或 HEAD 请求响应中的 Link 标头来发现元数据。

元数据类型

类别 描述
系统管理 由服务器维护;只读。包括 linksettypemediaTypesizemodified
核心元数据 由客户端管理(受服务器限制约束)。包括 upitemstitlecreator
用户定义 由用户创建的自定义词汇表和索引。

可修改性考量 核心元数据MAY 由客户端修改。为确保互操作性,服务器 MUST 使用标准 HTTP 标头来宣告其能力:

  1. 方法发现:服务器MUST 通过 Allow 标头宣告对 linkset 资源上 GET 和 PATCH 操作的支持。

  2. 补丁格式发现:服务器MUST 通过 Accept-Patch 标头宣告 对 JSON Merge Patch [RFC7386] 的支持: Accept-Patch: application/merge-patch+json

  3. 可选方法:服务器MAY 支持 PUT 或替代补丁格式; 如果支持,则这些内容MUST 分别包含在 Allow 和 Accept-Patch 标头中。

[!IMPORTANT] 客户端SHOULD NOT 假定支持 PUT 或特定补丁格式, 除非它们在资源标头中被宣告,并且MUST 优雅处理 405 Method Not Allowed 或 415 Unsupported Media Type 响应。

管理元数据 元数据通过与资源关联的linkset 资源 URI 进行交互来管理。服务器MUST 支持更新的并发控制。

9.2 创建资源

创建资源操作将一个新的被服务资源添加到现有容器中。此 操作同时处理数据资源和子容器的创建。

输入:

行为:

可能的响应:

新资源通过对目标容器 URI 使用 POST 创建,服务器分配 最终标识符。客户端MAY 通过 Slug 标头建议名称。 客户端MAY 通过在 POST 请求中 包含一个或多个 Link 标头,为新资源提供初始用户管理元数据,并遵循 [RFC8288] 中 Web Linking 的语法。服务器管理的元数据MUST 由服务器在创建时自动生成,并且MUST NOT 被 客户端提供的链接覆盖。

成功时,服务器MUST 返回 201 状态码,并在 Location 标头中包含新 URI。服务器MUST 包含 Link 标头, 用于关键服务器管理元数据,包括指向父容器的链接 (rel="up"),以及指向所创建资源的专用linkset 资源的链接 (rel="linkset"; type="application/linkset+json")。其他链接SHOULD 包括 rel="type"(表示 https://www.w3.org/ns/lws#Containerhttps://www.w3.org/ns/lws#DataResource)。正文MAY 为空或 包含资源的最小表示。所有元数据创建和链接MUST 与资源创建保持原子性,以维护一致性。

POST(到容器 URI)使用服务器分配的名称创建: 使用 POST 将新资源添加到现有容器内。服务器为该资源分配标识符, 可选择使用 Slug 标头提出建议。若 Slug 标头不与命名规则或现有 资源冲突,服务器MAY 采纳它。客户端按如下方式指示要创建的资源类型:

示例(POST 创建新的数据资源):

POST /alice/notes/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Type: text/plain
Content-Length: 47
Slug: shoppinglist.txt

milk
eggs
bread
butter
apples
orange juice

在此示例中,客户端正在向容器 /alice/notes/ 发布。 它提供 text/plain 内容(一份购物清单),并建议使用 shoppinglist.txt 作为新资源的名称。如果 /alice/notes/ 存在且客户端 已获授权,服务器将创建一个新的数据资源,并将其添加到该容器的成员关系中。

示例(对 POST 的响应 — 数据资源):

HTTP/1.1 201 Created
Location: /alice/notes/shoppinglist.txt
Content-Type: text/plain; charset=UTF-8
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Content-Length: 0

成功时,返回 201 Created,并在 Location 标头中包含新 URI。正文可以 为空或为最小表示。 如果目标容器 /alice/notes/ 不存在,则服务器 MUST 返回 404 错误状态,除非另一个状态码更合适。

创建容器要创建新的容器,客户端对现有父容器使用 POST,并带有一个指示 Container 类型的 Link 标头。例如:

POST /alice/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Length: 0
Slug: notes
Link: <https://www.w3.org/ns/lws#Container>; rel="type"

示例(对 POST 的响应 — 容器):

HTTP/1.1 201 Created
Location: /alice/notes/
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Content-Length: 0

这会在 /alice/notes/ 处创建一个新的容器,并带有服务器生成的 元数据,其中包括作为 https://www.w3.org/ns/lws#Containerrel="type"

关于 Create(HTTP 绑定)的附加说明:

管理和检索元数据(与创建相关): 虽然元数据主要通过读取操作检索,但它会在创建期间生成。客户端可以 在创建后立即对新资源 URI 使用 GET 或 HEAD 检索它。客户端可以使用 Prefer 标头请求包含特定元数据链接(通过关系类型)和 属性。

9.3 读取资源

检索现有资源的表示,或容器的列表。

读取资源操作通过 HTTP GET 请求(以及用于仅获取标头请求的 HEAD) 请求资源表示。行为取决于目标 URL 是容器还是非容器资源(数据资源)。服务器MUST 通过元数据区分资源类型。所有响应MUST 与 第 8.1 节定义的元数据集成,包括用于关键关系的 Link 标头,例如 rel="linkset"rel="up"rel="type"。服务器MUST 确保读取期间资源状态与其元数据之间的原子性。

GET(非容器资源)检索资源内容: 向资源 URI 发送 GET 以获取完整内容(如果已获授权)。以 200 OK 响应,正文包含 数据,Content-Type 与所存储的媒体类型匹配。服务器MUST 按照 [RFC7233] 支持 范围请求,以便部分检索。响应MUST 包含 ETag 标头,用于并发控制和 缓存。

示例(GET 一个文件):

GET /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
Accept: text/plain

这会请求 /alice/notes/shoppinglist.txt 的内容,表明客户端希望 以文本形式获取它。假定资源存在、是文本,并且客户端有权访问:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 34
ETag: "abc123456"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/>; rel="up"
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"

milk
cheese
bread
guacamole
soda
chocolate bars
hash
eggs

服务器返回了文本内容(共 34 字节,如 Content-Length 所示)。 内容正是该文件中存储的数据。ETag: "abc123456" 是用于缓存或并发目的的版本 标识符。响应包含用于元数据 可发现性的 Link 标头,并带有 uptype 等强制字段。

GET(容器资源)列出容器内容: 当目标 URI 对应于容器(通过元数据类型确定)时,GET 请求返回该 容器成员的列表。响应正文是 容器表示,如容器表示一节所定义,使用 LWS 容器媒体 类型。该列表包括每个成员的元数据:资源标识符(MUST)、类型(MUST)、媒体类型(对于 DataResources,MUST)、大小(SHOULD)以及 修改时间戳(SHOULD)。

示例(GET 一个容器):

GET /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Accept: application/ld+json

假定容器存在且客户端有权访问:

HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "container-etag-789"
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"

{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "/alice/notes/",
  "type": "Container",
  "totalItems": 2,
  "items": [
    {
      "type": "DataResource",
      "id": "/alice/notes/shoppinglist.txt",
      "mediaType": "text/plain",
      "size": 47,
      "modified": "2025-11-24T12:00:00Z"
    },
    {
      "type": ["DataResource", "http://example.org/customType"],
      "id": "/alice/notes/todo.json",
      "mediaType": "application/json",
      "size": 2048,
      "modified": "2025-11-24T13:00:00Z"
    }
  ]
}

在此示例中,/alice/notes/ 是一个容器。响应使用带有 LWS 上下文的 JSON-LD,列出带有必需元数据的成员。每个条目都包含其 typeidmediaTypesizemodified 时间戳作为扁平 属性。

在所有情况下,服务器MUST 在响应 标头中包含以下元数据:ETag(表示列表版本,它会在成员关系修改时变化),以及 Link 标头,其中 rel="type" 表明它是一个容器,并包含 rel="linkset"rel="up"

HEAD(任何资源或容器仅标头/元数据: LWS 服务器MUST容器和非容器均支持 HEAD [RFC9110], 返回与 GET 相同的标头(包括 ETag、Content-Type、用于元数据的 Link),但没有正文。这可以在不传输内容的情况下检索 元数据。

缓存和条件请求:LWS 利用 HTTP 缓存语义。服务器MUST 支持通过 If-None-Match(使用 ETag)或 If-Modified-Since 标头进行条件请求。如果资源或容器列表未更改,则响应 304 Not Modified,以避免冗余传输。所有 GET/HEAD 响应中MUST 提供 ETag, 用于并发和缓存支持。

可发现性和授权:为了增强可发现性,服务器SHOULD 在 401 Unauthorized 响应上包含带有 参数的 WWW-Authenticate 标头,以便在没有硬编码 URI 的情况下引导客户端。元数据链接SHOULD 在适用时包含。

9.4 更新资源

通过完整替换或部分补丁修改现有 [served resource] 的状态。

更新资源通过 PUT 请求(替换整个资源)或 PATCH 请求(应用 部分修改)修改现有被服务 资源的内容。客户端必须对资源 URL 拥有写访问权限才能执行这些 操作。 注:本节描述更新资源的主要内容。要更新其元数据,请见第 9.3.2 节。 LWS 服务器MUST 将资源 URI 上的 PUT 和 PATCH 请求处理为 仅对资源内容的修改,默认情况下不影响关联的linkset 资源。为了可选择地在单个原子操作中同时更新内容和 元数据,客户端MAY 在对资源 URI 的 PUT/PATCH 请求中包含 Link 标头,并指定偏好 'Prefer: set-linkset'(如 RFC 7240 中所定义)。在这种情况下,服务器MUST 将提供的 Link 标头解释为 对 linkset 的替换(对于 PUT)或部分更新(对于 PATCH),并同时应用 内容更改。此行为对服务器而言是OPTIONAL,但如果支持,MUST 通过 Prefer 标头显式调用,以防止无意 覆盖元数据。不支持组合更新的服务器MUST 忽略 该偏好或以 501 Not Implemented 响应。

PUT(替换完整资源) – 向资源 URI 发送 PUT,并在 正文中包含新的完整内容和匹配的 Content-Type(通常与现有类型一致)。PUT 对现有 资源是幂等的。为安全起见,包含带有当前 ETag 的 If-Match(依据第 7.3 节并发);不匹配会产生 412 Precondition Failed 或 409 Conflict。如果没有检查,更新是无条件的,但可能覆盖 并发更改。如果服务器支持资源的 Etags,它MUST 以 428 Precondition Required 响应拒绝缺少 If-Match 标头的无条件 PUT 请求。

示例(PUT 更新资源):

PUT /alice/personalinfo.json HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
If-Match: "abc123456"
{
"name": "Alice",
"age": 30,
"city": "New London",
"state": "Connecticut"
}

在此示例中,客户端正在更新 /alice/personalinfo.json 处的现有 JSON 资源。它 包含一个 If-Match 标头,其中带有它从早先 GET 或 HEAD 请求获得的 ETag "abc123456"。 服务器会将其与当前 ETag 比较;如果匹配,就继续用 所提供的 JSON 替换内容。如果不匹配,服务器会拒绝更新(因为该资源在此期间 已被其他人更改)。 成功响应:如果更新成功,服务器可以用 200 OK 响应,并可能包含 更新后的表示或某些确认信息(例如新内容或其中一部分)。或者, 服务器可以用 204 No Content 响应,表示成功但无正文(如果无需传达更多 信息,这尤其常见)。无论哪种情况,服务器SHOULD 包含新的 ETag 来表示新版本,如果返回正文,也可以包含 Content-Type。例如:

HTTP/1.1 204 No Content
ETag: "def789012"

这会告诉客户端更新已完成,并提供新的 ETag。如果服务器选择 返回更新后的内容,它可能使用 200 OK 并在正文中包含 JSON,同时 带有标头。

PATCH(部分更新) – HTTP PATCH 方法 [RFC5789] 允许客户端指定对资源的部分修改,而不是发送完整的新 内容。当资源很大且只有一小部分发生变化时,发送整个内容效率较低, 或者在并发编辑中希望应用特定更改时,这很有用。LWS 服务器MUST 至少支持 [RFC7386] 中定义的 JSON Merge Patch(application/merge-patch+json)。

更新资源元数据(对 Linkset 使用 HTTP PUT / PATCH) 资源的元数据通过修改其对应的linkset 资源来更新, 该资源通过带有 rel="linkset" 的 Link 标头发现。 完整替换(PUT):对linkset 资源 URI 发送 PUT 请求,并在正文中包含完整 linkset 文档,会替换该资源的所有元数据。 部分更新(PATCH):对linkset 资源 URI 发送 PATCH 请求,会添加、移除或 修改特定链接。

元数据的并发控制 因为资源的元数据可能由多个参与者修改,防止并发覆盖至关重要。 为确保数据完整性,LWS 服务器和客户端MUST 为所有 对linkset 资源的 PUT 和 PATCH 操作,实现使用条件请求 [RFC7232] 的乐观并发控制。 服务器职责: 服务器MUST 在其对linkset 资源的 GET 和 HEAD 请求响应中包含 Etag 标头。 在成功对 linkset 执行 PUT 或 PATCH 后,服务器MUST 为修改后的 linkset 生成新的、 唯一 Etag 值,并在响应的 Etag 标头中返回它。 客户端职责: 修改linkset 资源时,客户端MUST 包含一个 If-Match 标头,其中包含它最近收到的该资源 Etag。 处理规则: 如果 If-Match 标头值与 linkset 的当前 Etag 不匹配,服务器MUST 以 412 Precondition Failed 状态码拒绝请求。 如果对 linkset URI 的 PUT 或 PATCH 请求缺少 If-Match 标头,服务器MUST 以 428 Precondition Required 状态码拒绝请求 [RFC6585]。 示例(PUT 替换 linkset): 客户端首先获取 linkset 并接收其 ETag。

GET /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Accept: application/linkset+json
HTTP/1.1 200 OK
Content-Type: application/linkset+json
ETag: "meta-v1"
{
  "linkset": [
    {
      "anchor": "/alice/personalinfo.json",
      "describedby": [ { "href": "/schemas/personal-info.json" } ]
    }
  ]
}

客户端现在想要添加许可证。它构造一个新的完整 linkset 文档,并发送带有 If-Match 标头的 PUT 请求。

PUT /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/linkset+json
If-Match: "meta-v1"
{
  "linkset": [
    {
      "anchor": "/alice/personalinfo.json",
      "describedby": [ { "href": "/schemas/personal-info.json" } ],
      "license": [ { "href": "https://creativecommons.org/licenses/by/4.0/" } ]
    }
  ]
}

如果成功,服务器以成功响应,并返回新的 ETag。

HTTP/1.1 204 No Content
ETag: "meta-v2"

更新规则摘要 如果你只想更改资源的内容 → 对资源本身执行 PUT/PATCH。 如果你只想更改资源的链接(元数据)→ 对该资源关联的linkset 资源执行 PUT/PATCH。 如果你想同时更改内容和链接 → 对资源本身执行 PUT/PATCH,并包含适当的 Link 标头和 'Prefer: set-linkset'。同时设置默认关闭。

9.5 删除资源

永久移除资源及其关联元数据。

删除资源操作使用 HTTP DELETE 方法实现,如上述抽象 操作中所定义。本节指定输入、行为和响应的 HTTP 绑定。

DELETE 请求以要移除的资源或容器的 URI 为目标。客户端MAY 包含带有 ETag 的 If-Match 标头,以进行并发 检查。

删除和包含关系 删除资源时,服务器MUST 以原子方式将其从其 父容器items 列表中移除。父容器的 totalItems 计数SHOULD 相应更新,并且其 ETagMUST 被更新以反映该变更。

对于非容器资源,服务器移除资源内容、其关联元数据(linkset 资源),以及父容器中的包含关系引用。

对于容器资源,服务器默认执行非递归 删除。如果该容器非空且未请求递归,则服务器 MUST 以 409 Conflict 拒绝请求。服务器MAY 支持递归删除正在被删除的容器内的所有包含资源。 客户端MUST 使用 Depth: infinity 标头来请求 递归删除,如 [RFC4918] 中所定义。

成功时,服务器MUST 以 204 No Content 响应。服务器SHOULD 支持条件请求,如 [RFC9110] 中所定义。

如果客户端缺少授权,服务器MUST 返回 403 Forbidden(如果 客户端身份已知但权限不足)或 401 Unauthorized(如果未提供有效 身份验证)。在泄露资源存在性会造成安全风险的情况下, 服务器MAY 改为返回 404 Not Found。

示例(DELETE 非容器资源):

DELETE /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
If-Match: "abc123456"

假定 ETag 匹配且客户端已获授权,服务器会以原子方式删除资源、其元数据, 并将其从父容器 /alice/notes/ 中移除:

HTTP/1.1 204 No Content

示例(DELETE 非空容器且不递归):

DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>

假定 /alice/notes/ 包含资源,服务器会拒绝删除:

HTTP/1.1 409 Conflict
Content-Type: text/plain

Cannot delete container /alice/notes/ - container is not empty.

示例(如果支持,递归 DELETE 容器):

DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Depth: infinity

假定服务器支持递归且客户端对所有内容都有权限,服务器会以原子方式 删除该容器及其后代:

HTTP/1.1 204 No Content

9.6 HTTP 状态 映射摘要

此表将通用 LWS 响应(来自 第 8 节)映射到 HTTP 状态码和载荷,以保持一致性,并纳入诸如 分页、并发控制、配额约束和元数据集成等特定场景:

LWS 响应 HTTP 状态码 HTTP 载荷
成功(读取或更新,返回 数据) 200 OK 响应正文中的资源 表示(用于 GET,或在 PUT/PATCH 返回内容时),以及 相关标头(Content-Type、ETag、用于元数据的 Link,例如 rel="linkset"、 rel="up")。对于容器列表,包含带有规范性上下文和成员 元数据(ID、类型、大小、时间戳)的 JSON-LD。
已创建(新资源) 201 Created 通常没有响应正文(或新资源的最小表示)。 Location 标头设置为新资源的 URI。用于并发的 ETag 等标头MUST 被包含;还包括用于服务器管理 元数据的 Link 标头。
已删除(没有内容可返回) 204 No Content 无响应正文。表示资源已被删除,或请求成功且没有 其他内容可说。服务器MAY 对永久 删除使用 410 Gone。
错误请求(输入或约束无效) 400 Bad Request 解释错误所在的错误详情。服务器SHOULD 使用 [RFC9457] 中定义的 标准格式来提供结构化错误响应,例如带有 "type"、"title"、 "status"、"detail" 和 "instance" 等字段的 JSON 对象。

10. 访问请求和授予

访问请求和授予提供一种机制,使代理能够请求访问 资源,并使存储控制者能够在定义的约束下授予访问权限。 用于请求和授予访问权限的端点充当一种专用收件箱。

代理不会 将访问授予作为授权令牌呈现给服务器。 相反,访问授予作为一条记录,记录授权了什么、授予给谁、 以及在什么约束下授权。当访问授予被创建或撤销(删除)时, 服务器有责任调整任何底层访问策略,以反映该 变更。访问授予端点与特定策略 执行层之间的交互不在本规范范围内。

本节中定义的访问配置文件基于 开放数字版权语言(ODRL)中的概念,包括 动作、约束和被指派方。其他配置文件可以使用不同的概念框架。

议题:与 主要术语章节集成

本节定义以下术语:

  • 访问请求 — 由代理提交的数据对象,表达 对存储资源执行特定动作的请求,包括期望的范围 和约束。
  • 访问授予 — 由存储控制者创建的数据对象,表达 代理在某些 已定义约束内对存储资源 执行特定动作的能力。
  • 访问配置文件 — 访问配置文件 描述表达有效访问策略的要求。每个访问配置文件都由 URI 标识,并且服务器通过在其 存储描述资源中服务对象的 conformsTo 属性引用一个或多个访问配置文件,来表示对这些配置文件的支持。

10.1 发现

存储MAY 在其存储描述资源中宣告对访问请求访问授予的支持。当宣告此类支持时,描述 访问请求端点的服务 对象MUST 具有等于字符串 AccessRequestServicetype,并且描述访问授予端点的服务对象MUST 具有 等于字符串 AccessGrantServicetype。服务 对象SHOULD 包含一个 conformsTo 属性,其值为一个 由一个或多个 URI 组成的集合,用于标识该端点支持的访问配置文件。 可以包含其他属性:

示例 10:带有访问请求和授予 服务的存储描述
{
  "@context": [
    "https://www.w3.org/ns/lws/v1"
  ],
  "id": "https://storage.example/",
  "type": "Storage",
  "service": [
    {
      "type": "AccessRequestService",
      "serviceEndpoint": "https://access.example/request/",
      "conformsTo": ["https://www.w3.org/ns/lws#AccessProfile"]
    },
    {
      "type": "AccessGrantService",
      "serviceEndpoint": "https://access.example/grant/",
      "conformsTo": ["https://www.w3.org/ns/lws#AccessProfile"]
    }
  ]
}

10.2 数据模型

访问请求访问授予是一个数据 对象,用于表达身份和路由相关的属性,以及一个描述所 请求或许可操作的 access 对象。一个使用 ODRL 概念描述访问请求的配置文件 在10.3 访问配置文件中描述。

以下示例展示一个访问请求。该示例 使用10.4.1 JSON-LD 序列化中定义的 JSON-LD 序列化显示。

示例 11:访问请求
{
  "@context": [
    "https://www.w3.org/ns/lws/v1"
  ],
  "type": ["AccessRequest"],
  "inbox": "https://id.example/agent/inbox/",
  "storage": "https://storage.example/",
  "access": [{
    "type": ["AccessPolicy"],
    "action": ["read", "create"],
    "assignee": "https://id.example/agent",
    "target": {
      "type": "StorageResource",
      "value": ["https://storage.example/projects/"]
    },
    "constraint": [
      {
        "leftOperand": "purpose",
        "operator": "eq",
        "rightOperand": "https://purpose.example/collaboration"
      },
      {
        "leftOperand": "dateTime",
        "operator": "lteq",
        "rightOperand": "2026-06-09T10:00:00Z"
      }
    ]
  }]
}

以下示例展示一个访问授予。该示例 使用10.4.1 JSON-LD 序列化中定义的 JSON-LD 序列化显示。

示例 12:访问授予
{
  "@context": [
    "https://www.w3.org/ns/lws/v1"
  ],
  "type": ["AccessGrant"],
  "storage": "https://storage.example/",
  "access": [{
    "type": ["AccessPolicy"],
    "action": ["read"],
    "assignee": "https://id.example/agent",
    "target": {
      "type": "StorageResource",
      "value": ["https://storage.example/projects/"]
    },
    "constraint": [
      {
        "leftOperand": "purpose",
        "operator": "eq",
        "rightOperand": "https://purpose.example/collaboration"
      },
      {
        "leftOperand": "dateTime",
        "operator": "lteq",
        "rightOperand": "2026-06-09T10:00:00Z"
      }
    ]
  }]
}

访问请求访问授予上可以存在其他属性。

10.2.1 类型

type 属性表达文档的类型。

type 属性的值MUST 是一个或多个 术语绝对 URL 字符串。对于 访问请求,该值MUST 包含术语 AccessRequest。 对于访问授予,该值MUST 包含术语 AccessGrant。可以包含其他类型值。

此属性是REQUIRED

本文档为访问请求访问授予定义以下类型值:

  • AccessRequest代理请求访问资源。
  • AccessGrant存储 控制者作出的授权,用于授予 对资源的访问权限。
示例 13:type 属性
{
  "type": ["AccessGrant"]
}

10.2.2 存储

storage 属性标识 访问请求访问授予所限定到的 LWS 存储。

storage 属性的值MUST 是 URI。

此属性是REQUIRED

示例 14:storage 属性
{
  "storage": "https://storage.example/"
}

10.2.3 收件箱

inbox 属性指定一个 URI,用于接收与 访问请求访问授予 相关的通知 (见10.6 通知)。

inbox 属性的值MUST 是 URI。

此属性是OPTIONAL

示例 15:inbox 属性
{
  "inbox": "https://id.example/agent/inbox/"
}

10.2.4 访问

access 属性基于服务器支持的配置文件,描述一个或多个 访问配置文件的特征。一个基于 ODRL 信息模型的 配置文件在10.3 访问配置文件中描述。

access 属性的值MUST 是一个由一个或多个 对象组成的集合。

此属性是REQUIRED

10.3 访问配置文件

本规范定义一个基于 ODRL 信息模型ODRL 词汇表的访问配置文件,并用以下 URL 标识: https://www.w3.org/ns/lws#AccessProfile

10.3.1 类型

type 属性表达访问策略的类型。

type 属性的值MUST 是一个或多个 术语绝对 URL 字符串,并且MUST 包含 术语 AccessPolicy。可以包含其他类型值。

该属性是REQUIRED

示例 16:访问策略类型
{
  "access": [{
    "type": ["AccessPolicy"]
  }]
}

10.3.2 动作

action 属性描述代理希望执行 (在请求的情况下)或被授权执行(在授予的情况下)的 操作

action 属性的值MUST 是一个由一个或多个 字符串组成的集合。每个值MUST 对应服务器识别的操作。 必须支持以下值:readmodifycreatedeletereadmodifydelete 值由 ODRL 词汇表定义。 create 值由本 规范定义。

这些动作值与 LWS 操作的对应关系如下:

  • read — 检索资源或其元数据(HTTP GET、HEAD)
  • modify — 修改现有资源(HTTP PUT、PATCH)
  • create — 在容器内创建新资源(HTTP POST)
  • delete — 移除现有资源(HTTP DELETE)

此属性是REQUIRED

示例 17:action 属性
{
  "access": [{
    "action": ["read", "create"]
  }]
}

10.3.3 被指派方

assignee 属性标识请求访问的一方(在 请求的情况下)或被授予访问权限的一方(在授予的情况下)。

assignee 属性的值MUST 是 URI。公共 访问MAY 使用来自FOAF 词汇表Agent 类来 指派,其 URI 为 http://xmlns.com/foaf/0.1/Agent

此属性是REQUIRED

示例 18:assignee 属性
{
  "access": [{
    "assignee": "https://id.example/agent"
  }]
}

10.3.4 目标

target 属性标识 访问请求访问授予 适用的资源。

target 属性MUST 是包含以下属性的对象:

  • type — 标识 目标匹配器类型的术语绝对 URL 字符串
  • value — 用于标识 目标资源的一个或多个字符串组成的集合。

本规范定义以下 type 值以供 目标对象使用:

  • https://www.w3.org/ns/lws#DataResource — 匹配 类型为 lws:DataResource 的资源。
  • https://www.w3.org/ns/lws#Container — 匹配 类型为 lws:Container 的资源。
  • https://www.w3.org/ns/lws#StorageResource — 匹配 由存储管理的任何资源。

服务器MAY 支持其他类型值。

此属性是OPTIONAL

示例 19:带有 Resource 类型的 target 属性
{
  "access": [{
    "target": {
      "type": "StorageResource",
      "value": [
        "https://storage.example/data/2025",
        "https://storage.example/data/2026"
      ]
    }
  }]
}

10.3.5 约束

constraint 属性定义限制或限定所 请求或授予的访问的条件。此属性使用 ODRL 约束模型。

如果存在,constraint 属性的值MUST 是一个 约束对象集合。每个约束对象MUST 包含以下 属性:

  • leftOperand — 标识被约束操作数的字符串。
  • operator — 标识比较运算符的字符串。
  • rightOperand — 要比较的值。其类型取决于 leftOperand

当存在多个约束对象时,所有这些约束对象都MUST 被 满足。

宣告支持此配置文件的服务器MUST 支持以下 leftOperand 值:

  • client — 表示 HTTP 请求的客户端标识符
  • mediaType — 表示目标 HTTP 资源的媒体类型
  • type — 表示资源链接 标头中表达的类型 URL
  • purpose — 表示所 请求或授予访问的预期用途
  • dateTime — 表示当前日期时间

此属性是OPTIONAL

以下示例展示这些约束的使用:

10.3.5.1 目的约束

以下示例使用 purpose 作为 leftOperand 值,来描述所 请求或授予访问的预期 用途。当使用 eq 运算符时, rightOperand 值是标识目的的 URI。 当使用 isAnyOf 运算符时,rightOperand 值是目的 URI 数组,并且如果所声明的目的与列出值中的任一项匹配, 则满足约束:

示例 20:目的约束
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "purpose",
        "operator": "isAnyOf",
        "rightOperand": [
          "https://purpose.example/collaboration",
          "https://purpose.example/research"
        ]
      }
    ]
  }]
}
10.3.5.2 客户端约束

以下示例使用 client 作为 leftOperand 值,将访问限制 到特定客户端应用程序。当使用 eq 运算符时, rightOperand 值是标识客户端的 URI:

示例 21:客户端约束
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "client",
        "operator": "eq",
        "rightOperand": "https://app.example/client-id"
      }
    ]
  }]
}
10.3.5.3 媒体类型 约束

以下示例使用 mediaType 作为 leftOperand 值,将 访问限制到具有特定媒体类型的资源。当使用 eq 运算符 时,rightOperand 值是标识 IANA 媒体类型的字符串。当 使用 isAnyOf 运算符时,rightOperand 值 是媒体类型字符串数组,并且如果资源的 媒体类型与列出值中的任一项匹配,则允许访问:

示例 22:媒体类型约束
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "mediaType",
        "operator": "isAnyOf",
        "rightOperand": ["image/jpeg", "image/png"]
      }
    ]
  }]
}
10.3.5.4 资源类型 约束

所有 LWS 资源都将包含指示类型值的链接标头:

以下示例使用 type 作为 leftOperand 值,基于 HTTP Link 标头中 宣告的资源类型来限制访问。 当使用 eq 运算符时,rightOperand 值 是标识资源类型的 URI。当使用 isAnyOf 运算符时, rightOperand 值是类型 URI 数组,并且如果 资源的类型与列出值中的任一项匹配,则允许访问:

示例 24:资源类型约束
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "type",
        "operator": "isAnyOf",
        "rightOperand": [
          "https://type.example/Playlist",
          "https://type.example/Song"
        ]
      }
    ]
  }]
}
10.3.5.5 时间约束

以下示例使用 dateTime 作为 leftOperand 值,将访问限制 到特定时间窗口。gteq 运算符定义 窗口的开始,而 lteq 运算符定义结束。 时间约束的 rightOperand 值是 XML Schema dateTime 字符串:

示例 25:时间约束
{
  "access": [{
    "constraint": [
      {
        "leftOperand": "dateTime",
        "operator": "gteq",
        "rightOperand": "2026-03-09T12:00:00Z"
      },
      {
        "leftOperand": "dateTime",
        "operator": "lteq",
        "rightOperand": "2026-06-09T10:00:00Z"
      }
    ]
  }]
}
10.3.5.6 组合约束

当存在多个约束对象时,所有这些约束对象都MUST 被满足, 才允许访问。以下示例将访问限制为特定客户端 应用程序,并要求在特定日期之前:

示例 26:组合约束
{
  "access": [{
    "action": ["read"],
    "assignee": "https://id.example/agent",
    "target": {
      "type": "StorageResource",
      "value": ["https://storage.example/projects/"]
    },
    "constraint": [
      {
        "leftOperand": "dateTime",
        "operator": "lteq",
        "rightOperand": "2026-06-09T10:00:00Z"
      },
      {
        "leftOperand": "client",
        "operator": "eq",
        "rightOperand": "https://app.example/client-id"
      }
    ]
  }]
}

10.4 序列化

本节中定义的数据模型独立于任何特定的 序列化。

10.4.1 JSON-LD 序列化

本规范为访问请求访问授予定义 JSON-LD 序列化。使用此序列化的文档MUST 包含 @context 属性,其值是一个有序集合,并包含 https://www.w3.org/ns/lws/v1。可以 包含其他上下文条目以定义扩展术语。

与此序列化关联的媒体类型是 application/lws+json

示例 27:JSON-LD @context
{
  "@context": [
    "https://www.w3.org/ns/lws/v1"
  ]
}

10.5 协议

访问请求访问授予端点 是 LWS 容器,并且MUST 符合本规范中定义的规则。

这些端点至少需要支持 GET 和 POST 操作。DELETE 操作 是RECOMMENDED。其他操作MAY 受支持。

这些端点MUST 支持 10.4.1 JSON-LD 序列化中定义的 JSON-LD 序列化,用于请求和响应载荷。服务器 MAY 支持其他序列化。

代理 通过向 访问请求端点提交 POST 请求来 创建访问请求存储 控制者通过 向访问授予端点提交 POST 请求 创建访问授予

成功的 POST 操作MUST 以设置为 新资源 URL 的 Location 标头进行响应。

10.5.1 访问请求端点

  • POST / — 创建访问请求。
  • GET / — 检索访问请求列表。
  • GET /:id — 检索特定访问请求。
  • DELETE /:id — 取消访问请求。

10.5.2 访问授予端点

  • POST / — 创建访问授予。
  • GET / — 检索访问授予列表。
  • GET /:id — 检索特定访问授予。
  • DELETE /:id — 撤销访问授予。

10.6 通知

Issue 103:LWS 通知特性 work-item

本节需要与尚待定义的 LWS 通知章节保持一致。

通知提供一种机制,用于告知代理存储 控制者有关 访问请求访问授予的变更。当 访问请求访问授予上存在 inbox 属性时, 服务器SHOULD 向该端点传递 通知,告知被指派方该事件。

通知的序列化MUST 符合 LWS 通知数据模型的要求。

传递到 inbox 端点的通知MUST 符合 LWS 协议中为通知传递定义的要求。

本节中描述的通知机制可与 Linked Data Notifications 模式相比,在该模式中 通知通过 inbox 属性发现,并通过向该 inbox 发送 POST 请求进行传递。

10.6.1 通知事件

服务器SHOULD 响应以下事件发送通知:

服务器MAY 响应其他事件发送通知。

11. LWS 媒体类型

11.1 LWS 媒体类型

LWS 容器表示存储描述资源MUST 使用媒体类型 application/lws+json

虽然 LWS 容器表示使用 JSON-LD 约定,但 LWS 的约束和要求 使得使用特定媒体类型是合理的。因为 LWS 容器可被视为 JSON-LD 的受限配置文件, 实现SHOULDapplication/ld+json; profile="https://www.w3.org/ns/lws/v1" 媒体类型视为等同于 application/lws+json

11.1.1 内容协商

服务器MUST 支持容器表示的内容协商。 无论请求的媒体类型是什么,响应载荷MUST 相同 — 只有 Content-Type 响应标头会变化:

  • 如果客户端请求 application/lws+json,服务器MUSTContent-Type: application/lws+json 响应。
  • 如果客户端请求 application/ld+json,服务器MUSTContent-Type: application/ld+json 响应。
  • 如果客户端请求 application/json,服务器MUSTContent-Type: application/json 响应。

在这三种情况下,响应正文都是符合 LWS 容器 词汇表的同一个 JSON-LD 文档。服务器可以通过内容协商自由支持其他媒体类型 (例如 text/turtle)。

11.1.2 分页

某些复合资源,例如容器,可能包含大量资源。 为了允许客户端逐步检索列表,服务器SHOULD 对成员数量超过 服务器确定阈值的容器支持 分页。

11.1.2.1 分页模型

分页基于链接:服务器通过 HTTP Link 标头提供分页 URI [RFC8288], 允许客户端在不依赖数字偏移量的情况下导航完整列表。

当列表被分页时,响应正文仅包含当前页的条目。复合资源的 idtypetotalItems 属性 反映完整成员关系,而 items 仅包含当前页上的资源。

11.1.2.3 请求页面

客户端请求复合资源的 URI 以获得第一页。响应包含 分页 Link 标头,客户端可跟随这些标头检索后续页面。服务器MAY 也支持 通过先前扫描期间获得的分页 URI 直接访问特定页面。

当返回分页响应时,服务器MUST 以 200 OK 响应。响应正文中的 totalItems 属性SHOULD 反映所有页面中的条目总数, 而不仅仅是当前页。

11.1.2.4 示例: 分页容器

请求:

GET /alice/photos/ HTTP/1.1
Authorization: Bearer <token>
Accept: application/lws+json

响应(第一页):

HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page1-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Link: </alice/photos/?page=1>; rel="first"
Link: </alice/photos/?page=3>; rel="last"
Link: </alice/photos/?page=2>; rel="next"

{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "/alice/photos/",
  "type": "Container",
  "totalItems": 150,
  "items": [
    {
      "type": "DataResource",
      "id": "/alice/photos/vacation.jpg",
      "mediaType": "image/jpeg",
      "size": 248392,
      "modified": "2025-11-20T10:30:00Z"
    },
    {
      "type": "DataResource",
      "id": "/alice/photos/portrait.png",
      "mediaType": "image/png",
      "size": 102400,
      "modified": "2025-11-21T14:15:00Z"
    }
  ]
}

请求(下一页):

GET /alice/photos/?page=2 HTTP/1.1
Authorization: Bearer <token>
Accept: application/lws+json

响应(中间页):

HTTP/1.1 200 OK
Content-Type: application/lws+json
ETag: "photos-page2-etag"
Link: </alice/photos/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/>; rel="up"
Link: </alice/photos/.acl>; rel="acl"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Link: </alice/photos/?page=1>; rel="first"
Link: </alice/photos/?page=1>; rel="prev"
Link: </alice/photos/?page=3>; rel="next"
Link: </alice/photos/?page=3>; rel="last"

{
  "@context": "https://www.w3.org/ns/lws/v1",
  "id": "/alice/photos/",
  "type": "Container",
  "totalItems": 150,
  "items": [
    {
      "type": "DataResource",
      "id": "/alice/photos/sunset.jpg",
      "mediaType": "image/jpeg",
      "size": 315000,
      "modified": "2025-11-22T09:00:00Z"
    }
  ]
}

12. JSON-LD 上下文和词汇表

12.1 JSON-LD 上下文和 词汇表

12.1.1 规范性 JSON-LD 上下文

容器表示MUST 包含以下 @context 值:

"@context": "https://www.w3.org/ns/lws/v1"

规范性 JSON-LD 上下文文档定义了 容器表示中使用的短属性名与其在 LWS 和 相关词汇表中的完整 URI 之间的映射。上下文定义如下:

{
  "@context": {
    "@version": 1.1,
    "@protected": true,
    "lws": "https://www.w3.org/ns/lws#",
    "as": "https://www.w3.org/ns/activitystreams#",
    "schema": "https://schema.org/",
    "xs": "http://www.w3.org/2001/XMLSchema#",
    "id": "@id",
    "type": "@type",
    "Container": "lws:Container",
    "DataResource": "lws:DataResource",
    "items": "lws:items",
    "totalItems": "as:totalItems",
    "mediaType": "as:mediaType",
    "size": {
      "@id": "schema:size",
      "@type": "xs:long"
    },
    "modified": {
      "@id": "as:updated",
      "@type": "xs:dateTime"
    }
  }
}

该上下文是 @protected 的,确保术语定义不能被 其他上下文覆盖。

12.1.2 词汇表

LWS 词汇表定义了容器 表示中使用的以下类型和属性:

类型:

术语 URI 描述
Container lws:Container 包含其他资源的资源
DataResource lws:DataResource 承载数据的资源

属性:

术语 URI 描述
items lws:items 容器中包含的资源列表
totalItems as:totalItems 被包含资源的总数
mediaType as:mediaType 资源的媒体类型
size schema:size 资源大小,以字节为单位
modified as:updated 资源最后修改的日期时间

13. 资源标识

定义在 LWS Protocol 中如何标识和寻址资源,包括 URI 方案、资源命名约定和解析机制。本节可能会被移至 另一节;例如 Resource Access

此处有意留空

14. 可移植性考量

描述用于确保 LWS 实现能够跨不同 平台、环境和存储后端工作并保持互操作性的考量,并提供 可供性能力以支持更换存储提供者

此处有意留空

15. 安全考量

本节为非规范性内容。

正式的安全考量章节,涵盖威胁模型、安全要求,以及 安全 LWS 部署的实现指南。

OAuth 2.0 Security 当前最佳实践 [RFC9700] 中描述的建议适用于本 规范。

15.1 传输安全

本节为非规范性内容。

传输层安全性(TLS)是防止篡改、仿冒和 信息泄露的重要机制。受 TLS 保护的通信可按照 [RFC6125] 进行验证。 实现安全考量可见“传输层安全性(TLS)和数据报传输层安全性(DTLS)的安全使用建议” [RFC9325]。

15.2 令牌安全

本节为非规范性内容。

Bearer 令牌和数字凭证容易遭受盗窃和重放。缓解措施包括使用 合理较短的生命周期、将令牌绑定到特定受众,以及安全存储令牌。

15.3 访问请求和授予

本节为非规范性内容。

16. 隐私考量

本节为非规范性内容。

LWS Protocol 的隐私影响,包括数据最小化、用户同意,以及 保护隐私的实现模式。

凭证携带关于用户和代理的信息。虽然数字签名可以防止篡改, 但客户端或第三方仍可能读取未加密凭证内部的值。

因此,鼓励凭证颁发者创建仅包含身份验证或授权所必需信息的令牌, 并避免包含敏感属性,除非确有需要。

一般来说,将未加密凭证数据写入日志是一种反模式。在确有必要的情况下, 实现可以截断或哈希凭证,以保护凭证主体的隐私。

在 JWT 中使用假名标识符时,存储服务器仍可能能够随时间关联来自 同一代理的请求。 为在这种情况下保护用户隐私,客户端应用程序可以请求批量颁发 JWT,其中每个 JWT 只使用一次。 这不能防止存储服务器使用其他信息(例如 JWT 内容相似性或 来源 IP 地址)来关联请求。使用假名标识符时,授权服务器需要谨慎, 不要多次颁发相同标识符。

16.1 访问请求和授予

本节为非规范性内容。

17. IANA 考量

本节为非规范性内容。

17.1 well-known URI 注册表

本规范将以下值添加到由 RFC 5785 [RFC5785] 建立的“Well-Known URIs”注册表

17.2 OAuth 授权服务器元数据注册表

本规范将以下值添加到由 [RFC8414] 建立的“OAuth Authorization Server Metadata”注册表

17.3 application/lws+json 媒体类型

本规范专门注册 application/lws+json 媒体类型,用于 标识符合 Linked Web Storage 容器格式的文档。

注意,虽然 Linked Web Storage 格式使用 JSON-LD 约定,但 LWS 实现还有若干 约束和附加 要求,使得使用特定媒体类型是合理的。

因为 LWS 容器可被视为 JSON-LD 的受限配置文件,实现SHOULDapplication/ld+json; profile="https://www.w3.org/ns/lws/v1" 媒体类型视为等同于 application/lws+json

A. 致谢

本节为非规范性内容。

本规范大量借鉴了 Solid Protocol [Solid-Protocol],该协议由 Sarven Capadisli、Tim Berners-Lee、Kjetil Kjernsmo、Ruben Verborgh、Justin Bingham、Dmitri Zagidulin 随时间推移编辑而成。

B. 参考文献

B.1 规范性参考文献

[FOAF]
FOAF 词汇表规范 0.99(Paddington 版). Dan Brickley; Libby Miller. FOAF project. 2014年1月14日. URL: http://xmlns.com/foaf/spec/
[JSON-LD11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 2020年7月16日. W3C 推荐标准. URL: https://www.w3.org/TR/json-ld11/
[ODRL-MODEL]
ODRL 信息模型 2.2. Renato Iannella; Serena Villata. W3C. 2018年2月15日. W3C 推荐标准. URL: https://www.w3.org/TR/odrl-model/
[ODRL-VOCAB]
ODRL 词汇表与表达 2.2. Renato Iannella; Michael Steidl; Stuart Myles; Víctor Rodríguez-Doncel. W3C. 2018年2月15日. W3C 推荐标准. URL: https://www.w3.org/TR/odrl-vocab/
[OPENID-CONNECT-CORE]
OpenID Connect Core 1.0 incorporating errata set 2. N. Sakimura; J. Bradley; M. Jones; B. de Medeiros; C. Mortimore. OpenID Foundation. 2023年12月15日. 最终版. URL: https://openid.net/specs/openid-connect-core-1_0.html
[RFC2119]
用于 RFC 中表示要求级别的关键词. S. Bradner. IETF. 1997年3月. 当前最佳实践. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3986]
统一资源标识符(URI):通用 语法. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005年1月. 互联网 标准. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4918]
Web 分布式创作 与版本控制(WebDAV)的 HTTP 扩展. L. Dusseault, Ed. IETF. 2007年6月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc4918
[RFC5789]
HTTP 的 PATCH 方法. L. Dusseault; J. Snell. IETF. 2010年3月. 提议标准. URL: https://httpwg.org/specs/rfc5789.html
[RFC6585]
附加 HTTP 状态码. M. Nottingham; R. Fielding. IETF. 2012年4月. 提议标准. URL: https://httpwg.org/specs/rfc6585.html
[RFC6749]
OAuth 2.0 授权 框架. D. Hardt, Ed. IETF. 2012年10月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc6749
[RFC6750]
OAuth 2.0 授权框架:Bearer 令牌用法. M. Jones; D. Hardt. IETF. 2012年10月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc6750
[RFC7231]
超文本传输协议(HTTP/1.1): 语义和内容. R. Fielding, Ed.; J. Reschke, Ed. IETF. 2014年6月. 提议标准. URL: https://httpwg.org/specs/rfc7231.html
[RFC7232]
超文本传输协议(HTTP/1.1): 条件请求. R. Fielding, Ed.; J. Reschke, Ed. IETF. 2014年6月. 提议 标准. URL: https://httpwg.org/specs/rfc7232.html
[RFC7233]
超文本传输协议(HTTP/1.1):范围 请求. R. Fielding, Ed.; Y. Lafon, Ed.; J. Reschke, Ed. IETF. 2014年6月. 提议标准. URL: https://httpwg.org/specs/rfc7233.html
[RFC7240]
HTTP 的 Prefer 标头. J. Snell. IETF. 2014年6月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc7240
[RFC7386]
JSON Merge Patch. P. Hoffman; J. Snell. IETF. 2014年10月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc7386
[RFC8174]
RFC 2119 关键词中大写与小写的歧义. B. Leiba. IETF. 2017年5月. 当前最佳实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8288]
Web 链接. M. Nottingham. IETF. 2017年10月. 提议标准. URL: https://httpwg.org/specs/rfc8288.html
[RFC8414]
OAuth 2.0 授权服务器 元数据. M. Jones; N. Sakimura; J. Bradley. IETF. 2018年6月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc8414
[RFC8693]
OAuth 2.0 Token Exchange. M. Jones; A. Nadalin; B. Campbell, Ed.; J. Bradley; C. Mortimore. IETF. 2020年1月. 提议 标准. URL: https://www.rfc-editor.org/rfc/rfc8693
[RFC9068]
OAuth 2.0 访问令牌的 JSON Web Token(JWT)配置文件. V. Bertocci. IETF. 2021年10月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc9068
[RFC9110]
HTTP 语义. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. 2022年6月. 互联网标准. URL: https://httpwg.org/specs/rfc9110.html
[rfc9112]
HTTP/1.1. R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed. IETF. 2022年6月. 互联网标准. URL: https://httpwg.org/specs/rfc9112.html
[RFC9264]
Linkset:链接集的媒体类型和链接关系类型. E. Wilde; H. Van de Sompel. IETF. 2022年7月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc9264
[RFC9457]
HTTP API 的问题详情. M. Nottingham; E. Wilde; S. Dalal. IETF. 2023年7月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc9457
[URL]
URL Standard. Anne van Kesteren. WHATWG. 现行标准. URL: https://url.spec.whatwg.org/
[WebArch]
万维网架构,卷一. Ian Jacobs; Norman Walsh. W3C. 2004年12月15日. W3C 推荐标准. URL: https://www.w3.org/TR/webarch/
[XMLSCHEMA11-2]
W3C XML Schema 定义语言(XSD)1.1 第 2 部分:数据类型. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 2012年4月5日. W3C 推荐标准. URL: https://www.w3.org/TR/xmlschema11-2/

B.2 资料性参考文献

[LDN]
Linked Data Notifications. Sarven Capadisli; Amy Guy. W3C. 2017年5月2日. W3C 推荐标准. URL: https://www.w3.org/TR/ldn/
[RFC5785]
定义 Well-Known 统一资源 标识符(URI). M. Nottingham; E. Hammer-Lahav. IETF. 2010年4月. 提议 标准. URL: https://www.rfc-editor.org/rfc/rfc5785
[RFC6125]
在传输层安全性(TLS)上下文中使用 X.509(PKIX)证书表示和验证 基于域的应用服务身份. P. Saint-Andre; J. Hodges. IETF. 2011年3月. 提议标准. URL: https://www.rfc-editor.org/rfc/rfc6125
[RFC8259]
JavaScript Object Notation(JSON)数据 交换格式. T. Bray, Ed. IETF. 2017年12月. 互联网标准. URL: https://www.rfc-editor.org/rfc/rfc8259
[RFC9325]
传输层安全性(TLS)和数据报传输层安全性(DTLS)的安全使用建议. Y. Sheffer; P. Saint-Andre; T. Fossati. IETF. 2022年11月. 当前最佳实践. URL: https://www.rfc-editor.org/rfc/rfc9325
[RFC9700]
OAuth 2.0 Security 当前最佳实践. T. Lodderstedt; J. Bradley; A. Labunets; D. Fett. IETF. 2025年1月. 当前最佳实践. URL: https://www.rfc-editor.org/rfc/rfc9700
[Solid-Protocol]
Solid Protocol. Sarven Capadisli; Tim Berners-Lee; Kjetil Kjernsmo. Solid Community Group. 2024年5月12日. 社区小组报告草案. URL: https://solidproject.org/TR/protocol