ERC-5573: 使用以太坊登录功能,ReCaps
在使用以太坊登录之上的机制,通过可扩展的作用域机制对委托功能进行知情同意
Authors | Oliver Terbu (@awoie), Jacob Ward (@cobward), Charles Lehner (@clehner), Sam Gbafa (@skgbafa), Wayne Chang (@wyc), Charles Cunningham (@chunningham) |
---|---|
Created | 2021-07-20 |
Discussion Link | https://ethereum-magicians.org/t/eip-5573-siwe-recap/10627 |
Requires | EIP-4361 |
摘要
ERC-4361,或使用以太坊登录(SIWE),描述了以太坊账户如何与链下服务进行身份验证。本提案,称为 ReCaps,描述了 SIWE 之上的一个机制,以提供知情同意,授权依赖方行使某些范围内的功能。依赖方如何针对目标资源进行身份验证不在本规范的范围内,并且取决于目标资源的实现。
动机
SIWE ReCaps 通过减少用户摩擦、链上状态并通过在使用以太坊登录(ERC-4361)之上引入知情同意和确定性的能力对象来提高安全性,从而解锁协议和/或 API 的开发者集成。
虽然 SIWE 专注于针对启动 SIWE 流程的服务(依赖方或 SIWE 客户端)验证以太坊账户的身份,但对于已验证的以太坊账户授权依赖方代表以太坊账户与第三方服务(资源服务)交互,没有规范的方法。依赖方可能希望代表以太坊账户与另一个服务交互,例如为以太坊账户提供数据存储的服务。本规范引入了一种机制,允许服务(或更常见的依赖方)将身份验证和此类授权结合起来,同时保持安全性和优化用户体验。
请注意,这种方法类似于结合 OpenID Connect(SIWE 身份验证)和 OAuth2(SIWE ReCap)的机制,其中 SIWE ReCap 在 SIWE 提供的身份验证之上实现基于能力的授权。
规范
本规范有三个不同的受众:
- 希望集成 ReCaps 以使用支持对象能力的任何协议和 API 进行身份验证的 Web3 应用程序开发人员。
- 想要学习如何定义自己的 ReCaps 的协议或 API 开发人员。
- 想要改进 ReCaps 用户界面的钱包实现者。
术语和定义
- ReCap - 符合本规范的 SIWE 消息,即在
Resources
部分中包含至少一个 ReCap URI,并将相应的人类可读的 ReCap 声明附加到 SIWEstatement
中。 - ReCap URI - 一种 URI,可解析为 ReCap 详细信息对象。
- ReCap 详细信息对象 - 一个 JSON 对象,描述与 ReCap 能力相关的操作,以及可选的资源。
- 资源服务(RS)- 为以太坊账户提供第三方服务的实体。
- SIWE 客户端(SC)- 启动授权(SIWE 身份验证和 ReCap 流程)的实体。
- 依赖方(RP)- 在授权上下文中与 SC 相同。
概述
本规范定义了以下内容:
- ReCap SIWE 扩展
- ReCap 能力
- ReCap URI 方案
- ReCap 详细信息对象模式
- ReCap 翻译算法
- ReCap 验证
ReCap SIWE 扩展
ReCap 是一种 ERC-4361 消息,遵循特定的格式,允许以太坊账户通过知情同意将其一组“ReCap 能力”委托给依赖方。ReCap 能力 必须 由 SIWE 消息的 Resources
数组中的最后一个条目表示,该条目 必须 使用 ReCap 翻译算法以人类可读的形式确定性地将 ReCap 能力翻译为 SIWE 消息中的 statement
字段。
以下 SIWE 消息字段用于进一步定义(或限制)所有 ReCap 能力的范围:
URI
字段 必须 指定预期的依赖方,例如https://example.com
、did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
。预计 RS 在调用 ReCap 能力的操作之前,会对依赖方进行身份验证。Issued At
字段 必须 用于指定 ReCap 能力的发布日期。- 如果存在,
Expiration Time
字段 必须 用作 ReCap 能力的到期时间,即 RS 将不再接受以此形式表示的能力调用的时间。 - 如果存在,
Not Before
字段 必须 用作在 RS 开始接受消息中表达的能力调用之前必须到期的时间。
以下是带有 SIWE ReCap 扩展的 SIWE 消息的非规范性示例:
example.com 希望您使用您的以太坊账户登录:
0x0000000000000000000000000000000000000000
我进一步授权声明的 URI 代表我执行以下操作:(1)“example”:“append”,“read”,用于“https://example.com”。(2)“other”:“action”,用于“https://example.com”。(3)“example”:“append”,“delete”,用于“my:resource:uri.1”。(4)“example”:“append”,用于“my:resource:uri.2”。(5)“example”:“append”,用于“my:resource:uri.3”。
URI: did:key:example
Version: 1
Chain ID: 1
Nonce: mynonce1
Issued At: 2022-06-21T12:00:00.000Z
Resources:
- urn:recap:eyJhdHQiOnsiaHR0cHM6Ly9leGFtcGxlLmNvbSI6eyJleGFtcGxlL2FwcGVuZCI6W10sImV4YW1wbGUvcmVhZCI6W10sIm90aGVyL2FjdGlvbiI6W119LCJteTpyZXNvdXJjZTp1cmkuMSI6eyJleGFtcGxlL2FwcGVuZCI6W10sImV4YW1wbGUvZGVsZXRlIjpbXX0sIm15OnJlc291cmNlOnVyaS4yIjp7ImV4YW1wbGUvYXBwZW5kIjpbXX0sIm15OnJlc291cmNlOnVyaS4zIjp7ImV4YW1wbGUvYXBwZW5kIjpbXX19LCJwcmYiOltdfQ
ReCap 能力
ReCap 能力由它们的 ReCap URI 标识,该 URI 解析为 ReCap 详细信息对象,该对象定义了关联的操作和可选的目标资源。每个 ReCap 能力的范围由 SIWE 消息中的通用字段衰减,如前一章所述,例如 URI
,Issued At
,Expiration Time
,Not Before
。
ReCap URI 方案
ReCap URI 以 urn:recap:
开头,后跟 ReCap 详细信息对象的未填充的 base64url 编码的有效负载。请注意,术语 base64url 在 RFC4648 - 带有 URL 和文件名安全字母的 Base 64 编码中定义。如果存在,Recap URI 必须 占据 SIWE 资源列表的最后一个条目。
以下是 ReCap 能力的非规范性示例:
urn:recap:eyJhdHQiOnsiaHR0cHM6Ly9leGFtcGxlLmNvbS9waWN0dXJlcy8iOnsiY3J1ZC9kZWxldGUiOlt7fV0sImNydWQvdXBkYXRlIjpbe31dLCJvdGhlci9hY3Rpb24iOlt7fV19LCJtYWlsdG86dXNlcm5hbWVAZXhhbXBsZS5jb20iOnsibXNnL3JlY2VpdmUiOlt7Im1heF9jb3VudCI6NSwidGVtcGxhdGVzIjpbIm5ld3NsZXR0ZXIiLCJtYXJrZXRpbmciXX1dLCJtc2cvc2VuZCI6W3sidG8iOiJzb21lb25lQGVtYWlsLmNvbSJ9LHsidG8iOiJqb2VAZW1haWwuY29tIn1dfX0sInByZiI6WyJ6ZGo3V2o2Rk5TNHJVVWJzaUp2amp4Y3NOcVpkRENTaVlSOHNLUVhmb1BmcFNadUF3Il19
能力字符串
能力字符串标识命名空间中的操作或能力。它们被序列化为 <namespace>/<ability>
。命名空间和能力 必须 仅包含字母数字字符以及字符 .
、*
、_
、+
、-
,符合正则表达式 ^[a-zA-Z0-9.*_+-]$
。整个能力字符串 必须 符合 ^[a-zA-Z0-9.*_+-]+\/[a-zA-z0-9.*_+-]+$
。例如,crud/update
的能力命名空间为 crud
,能力名称为 update
。
ReCap 详细信息对象模式
ReCap 详细信息对象表示依赖方被授权代表以太坊账户在 SIWE 消息中定义的有效期内调用哪些资源上的哪些操作。它还可以包含 RS 可能需要验证能力调用的其他信息。ReCap 详细信息对象 必须 遵循以下 JSON 模式:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"att": {
"type": "object",
"propertyNames": {
"format": "uri"
},
"patternProperties": {
"^.+:.*$": {
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9.*_+-]+\/[a-zA-z0-9.*_+-]+$": {
"type": "array",
"items": {
"type": "object"
}
}
},
"additionalProperties": false,
"minProperties": 1
}
},
"additionalProperties": false,
"minProperties": 1
},
"prf": {
"type": "array",
"items": {
"type": "string",
"format": "CID"
},
"minItems": 1
}
}
}
ReCap 详细信息对象定义了以下属性:
att
:(有条件)如果存在,att
必须 是一个 JSON 对象,其中每个键都是一个 URI,每个值都是一个对象,其中包含作为键的能力字符串和一个相应的值,该值是操作的限定词数组(即限制或要求)。对象的键 必须 按字典顺序排序。prf
:(有条件)如果存在,prf
必须 是一个字符串值 JSON 数组,其中至少有一个条目,其中每个值都是一个有效的 Base58 编码的 CID,用于标识父能力,如果 SIWEaddress
未标识att
条目的控制器,则授权以太坊账户执行att
中的一个或多个条目。
att
字段中的对象(包括嵌套对象) 必须 不包含重复的键,并且 必须 按字典顺序对其键进行排序,分为两个步骤:
- 按字节值排序。
- 如果一个字符串以另一个字符串开头,则较短的字符串先出现(例如,
msg/send
出现在msg/send-to
之前)
这与 JavaScript 中的 Array.sort()
方法相同。在下面的示例中,crud/delete
必须 出现在 crud/update
和 other/action
之前,类似地,msg/receive
必须 出现在 msg/send
之前。
以下是带有 att
和 prf
的 ReCap 能力对象的非规范性示例:
{
"att":{
"https://example.com/pictures/":{
"crud/delete": [{}],
"crud/update": [{}],
"other/action": [{}]
},
"mailto:username@example.com":{
"msg/receive": [{
"max_count": 5,
"templates": ["newsletter", "marketing"]
}],
"msg/send": [{ "to": "someone@email.com" }, { "to": "joe@email.com" }]
}
},
"prf":["bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa"]
}
在上面的示例中,授权依赖方对资源 https://example.com/pictures/
执行操作 crud/update
、crud/delete
和 other/action
,没有任何限制。此外,授权依赖方对资源 mailto:username@example.com
执行操作 msg/send
和 msg/recieve
,其中 msg/send
仅限于发送到 someone@email.com
或 joe@email.com
,而 msg/recieve
仅限于最多 5 个且模板为 newsletter
或 marketing
。请注意,依赖方可以在 RS 中单独且独立地调用每个操作。此外,ReCap 能力对象包含 RS 在验证期间需要的一些其他信息。定义此数据的结构和语义的责任在于 RS。这些操作和限制语义是示例,并非旨在被普遍理解。出现在与能力字符串关联的数组中的 Nota Bene 对象表示对能力使用的限制。空对象意味着可以在没有限制的情况下执行操作,但没有对象的空数组意味着没有以有效方式使用此能力的方法。
预计 RS 实现者会定义他们想要通过 ReCap 详细信息对象公开哪些资源,以及他们想要允许用户调用哪些操作。
此示例预计会转换为以下 recap-transformed-statement
(对于 URI
https://example.com
):
我进一步授权声明的 URI 代表我执行以下操作:(1)“crud”:“delete”,“update”,用于“https://example.com/pictures/”。(2)“other”:“action”,用于“https://example.com/pictures/”。(3)“msg”:“receive”,“send”,用于“mailto:username@example.com”。
此示例还预计会转换为以下 recap-uri
:
urn:recap:eyJhdHQiOnsiaHR0cHM6Ly9leGFtcGxlLmNvbS9waWN0dXJlcy8iOnsiY3J1ZC9kZWxldGUiOlt7fV0sImNydWQvdXBkYXRlIjpbe31dLCJvdGhlci9hY3Rpb24iOlt7fV19LCJtYWlsdG86dXNlcm5hbWVAZXhhbXBsZS5jb20iOnsibXNnL3JlY2VpdmUiOlt7Im1heF9jb3VudCI6NSwidGVtcGxhdGVzIjpbIm5ld3NsZXR0ZXIiLCJtYXJrZXRpbmciXX1dLCJtc2cvc2VuZCI6W3sidG8iOiJzb21lb25lQGVtYWlsLmNvbSJ9LHsidG8iOiJqb2VAZW1haWwuY29tIn1dfX0sInByZiI6WyJ6ZGo3V2o2Rk5TNHJVVWJzaUp2amp4Y3NOcVpkRENTaVlSOHNLUVhmb1BmcFNadUF3Il19
合并能力对象
只要遵循字段内容的排序规则,任何两个 Recap 对象都可以通过递归连接其字段元素来合并在一起。例如,两个 recap 对象:
{
"att": {
"https://example1.com": {
"crud/read": [{}]
}
},
"prf": ["bafyexample1"]
}
{
"att": {
"https://example1.com": {
"crud/update": [{
"max_times": 1
}]
},
"https://example2.com": {
"crud/delete": [{}]
}
},
"prf": ["bafyexample2"]
}
合并为:
{
"att": {
"https://example1.com": {
"crud/read": [{}],
"crud/update": [{
"max_times": 1
}]
},
"https://example2.com": {
"crud/delete": [{}]
}
},
"prf": ["bafyexample1", "bafyexample2"]
}
ReCap 翻译算法
在对给定的 SIWE 消息应用 ReCap 翻译算法后,该消息 可能 包括预定义的 statement
,ReCap SIWE 消息中的 recap-transformed-statement
必须 符合以下 ABNF:
recap-transformed-statement = statement recap-preamble 1*(" " recap-statement-entry ".")
; 请参阅 ERC-4361 获取 input-statement 的定义
recap-preamble = "我进一步授权声明的 URI 代表我执行以下操作:"
recap-statement-entry = "(" number ") " action-namespace ": "
action-name *("," action-name) "for"
recap-resource
; 请参阅 RFC8259 获取 number 的定义
ability-namespace = string
; 请参阅 RFC8259 获取 string 的定义
ability-name = string
; 请参阅 RFC8259 获取 string 的定义
recap-resource = string
; 请参阅 RFC8259 获取 string 的定义
必须 执行以下算法或产生相同输出的算法来生成 SIWE ReCap 转换的声明。
输入:
- 令
recap-uri
为 ReCap URI,它表示要在 SIWE 消息中编码的 ReCap 能力,并且其中包含符合 ReCap 详细信息对象模式的 ReCap 详细信息对象。 - [可选] 令
statement
为符合 ERC-4361 的输入 SIWE 消息的声明字段。 算法: - 令
recap-transformed-statement
为一个空字符串值。 - 如果
statement
存在,则执行以下操作:- 将
siwe
的statement
字段的值附加到recap-transformed-statement
。 - 将单个空格字符
" "
附加到recap-transformed-statement
。
- 将
- 将以下字符串附加到
recap-transformed-statement
:"我进一步授权声明的 URI 代表我执行以下操作:"
。 - 令
numbering
为从 1 开始的整数。 - 令
attenuations
为 ReCap 详细信息对象的att
字段 - 对于
attenuations
中的每个键和值对(从第一个条目开始),执行以下操作:- 令
resource
为键,abilities
为值 - 按其
ability-namespace
对abilities
对象的键进行分组 - 对于每个
ability-namespace
,执行以下操作:- 将字符串连接
" ("
、numbering
、")"
附加到recap-transformed-statement
。 - 将字符串连接
'
、ability-namespace
、':
附加到recap-transformed-statement
。 - 对于
ability-namespace
组中的每个ability-name
,执行以下操作:- 将字符串连接
'
、ability-name
、'
附加到recap-transformed-statement
- 如果不是最后一个
ability-name
,则将,
附加到recap-transformed-statement
- 将字符串连接
- 将
for '
、resource
、'.
附加到recap-transformed-statement
- 将
numbering
增加 1
- 将字符串连接
- 令
- 返回
recap-transformed-statement
。
ReCap 验证算法
必须 执行以下算法或产生相同输出的算法来验证 SIWE ReCap。
输入:
- 令
recap-siwe
为符合 ERC-4361 和本 EIP 的输入 SIWE 消息。 - 令
siwe-signature
为签名recap-siwe
的输出,如 ERC-4361 中定义。 算法: - 使用
recap-siwe
和siwe-signature
作为输入执行 ERC-4361 签名验证。 - 令
uri
为recap-siwe
的 uri 字段。 - 令
recap-uri
为从recap-siwe
的资源字段的最后一个条目中获取的 recap URI。 - 令
recap-transformed-statement
为使用uri
和recap-uri
作为输入执行上述ReCap Translation Algorithm
的结果。 - 断言
recap-siwe
的声明字段以recap-transformed-statement
结尾。
实现者指南
待定
Web3 应用程序实现者
待定
钱包实现者
待定
协议或 API 实现者
待定
理由
待定
安全注意事项
资源服务实现者不应将 ReCaps 视为持有者令牌,而应要求额外验证依赖方的身份。针对资源服务验证依赖方的过程不在本规范的范围内,可以通过各种不同的方式完成。
版权
版权和相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Oliver Terbu (@awoie), Jacob Ward (@cobward), Charles Lehner (@clehner), Sam Gbafa (@skgbafa), Wayne Chang (@wyc), Charles Cunningham (@chunningham), "ERC-5573: 使用以太坊登录功能,ReCaps [DRAFT]," Ethereum Improvement Proposals, no. 5573, July 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5573.