5个版本 (3个破坏性更新)

0.4.0 2023年3月27日
0.3.1 2022年8月11日
0.3.0 2022年6月14日
0.2.0 2022年4月5日
0.1.0 2022年4月2日

#276 in 身份验证

每月 26 次下载

MIT/Apache

300KB
4K SLoC

Crates.io Docs Coverage

dcaf-rs

ACE-OAuth框架 (RFC 9200) 的实现。

此crate实现了在RFC 9200中定义的ACE-OAuth(使用OAuth 2.0框架的受限环境身份验证和授权)框架。主要功能包括CBOR-(反)序列化数据模型,如AccessTokenRequest,以及创建COSE加密/签名访问令牌的可能性(如标准中所述),以及解密/验证函数。必须由用户通过实现CoseEncryptCipherCoseSignCipher来提供加密函数的实现。

请注意,实际上传输序列化值(例如,通过CoAP)或提供ACE-OAuth RFC中没有提到的更复杂的功能(例如,授权服务器的权限管理系统)超出了此crate的范围。这同样适用于前一段中提到的加密函数。

选择DCAF这个名字是因为最终,计划为此crate提供在Delegated CoAP Authentication and Authorization Framework (DCAF)中指定的功能,该框架在draft-gerdes-ace-dcaf-authorize中指定(在ACE-OAuth之前指定,并激发了其中许多设计选择)——具体来说,计划支持使用CAM(客户端授权管理器)而不是仅使用SAM(服务器授权管理器),就像在ACE-OAuth中做的那样。与现有的C语言中的DCAF实现(我们将称为libdcaf以区分dcaf,它指的是此crate)的兼容性也是一个额外的设计目标,尽管主要目标仍然是支持ACE-OAuth。

由于本软件包的一个可能的用例是在受限制的物联网设备上使用,因此需求最小化——因此,虽然仍然需要 alloc,但本软件包通过省略默认的 std 功能,提供了 no_std 支持。

用法

[dependencies]
dcaf = { version = "^0.3" }

或者,如果您计划在 no_std 环境中使用此软件包

[dependencies]
dcaf = { version = "^0.3", default-features = false }

示例

如前所述,本软件包的主要功能是 ACE-OAuth 数据模型和令牌创建/验证函数。我们将在这里快速介绍这两者。

数据模型

例如,假设您(客户端)希望从授权服务器请求访问令牌。为此,您需要创建一个 AccessTokenRequest,它至少需要包含一个 client_id。我们还将指定一个受众、作用域(使用 TextEncodedScope——注意,二进制编码的作用域或 AIF 编码的作用域也可以工作),以及一个 ProofOfPossessionKey(访问令牌应绑定到的密钥)在 req_cnf 字段中。

创建、序列化和反序列化此类结构将如下所示

use dcaf::{AccessTokenRequest, ToCborMap, ProofOfPossessionKey, TextEncodedScope};

let request = AccessTokenRequest::builder()
   .client_id("myclient")
   .audience("valve242")
   .scope(TextEncodedScope::try_from("read")?)
   .req_cnf(ProofOfPossessionKey::KeyId(base64::decode("6kg0dXJM13U")?))
   .build()?;
let mut encoded = Vec::new();
request.clone().serialize_into(&mut encoded)?;
assert_eq!(AccessTokenRequest::deserialize_from(encoded.as_slice())?, request);

访问令牌

在上一个示例之后,假设我们现在想要创建一个包含现有 key 以及关于令牌受众和发行者的声明的已签名访问令牌,使用现有的类型为 FakeCrypto[^cipher] 的加密器

use dcaf::token::CoseCipher;


let rng = FakeRng;
let key = CoseKeyBuilder::new_symmetric_key(vec![1,2,3,4,5]).key_id(vec![0xDC, 0xAF]).build();
let claims = ClaimsSetBuilder::new()
     .audience(String::from("coaps://rs.example.com"))
     .issuer(String::from("coaps://as.example.com"))
     .claim(CwtClaimName::Cnf, key.clone().to_cbor_value()?)
     .build();
let token = sign_access_token::<FakeCrypto, FakeRng>(&key, claims, None, None, None, rng)?;
assert!(verify_access_token::<FakeCrypto>(&key, &token, None).is_ok());

[^cipher]:注意,我们在此故意省略了关于 cipher 实现的细节,因为此类实现将不在本软件包的范围内。

提供的数据模型

令牌端点

最常用的模型可能是令牌端点的 AccessTokenRequestAccessTokenResponse,如 RFC 9200 第 5.8 节 所述。在发生错误的情况下,应使用 ErrorResponse

在初始未授权资源请求消息之后,可以使用 AuthServerRequestCreationHint 提供额外的信息给客户端,如 RFC 9200 第 5.3 节 所述。

常见数据类型

一些跨多个场景使用的类型包括

创建访问令牌

要创建访问令牌,您可以使用encrypt_access_tokensign_access_token,具体取决于您是否希望访问令牌被包装在COSE_Encrypt0COSE_Sign1结构中。计划在未来支持两者的组合。如果您想要创建一个针对多个接收者(每个接收者都有自己的密钥)的令牌,您可以使用encrypt_access_token_multiplesign_access_token_multiple

这两个函数都接受一个包含应包含在访问令牌中的声明的ClaimsSet,用于加密或签名令牌的密钥,可选的aad(附加认证数据),受/不受保护的头部和一个由类型参数T标识的加密(下面将进一步解释)。请注意,如果您传入的头部设置了加密也要设置的字段,函数将失败并返回一个HeaderAlreadySet错误。函数将返回包含访问令牌的不可见ByteStringResult

验证和解密访问令牌

为了验证或解密表示为ByteString的现有访问令牌,请分别使用verify_access_tokendecrypt_access_token。如果令牌是为多个接收者(每个接收者都有自己的密钥)创建的,请使用verify_access_token_multipledecrypt_access_token_multiple

这两个函数都接受访问令牌,用于解密或验证的密钥,可选的aad(附加认证数据)和一个实现加密操作的加密算法,由类型参数T标识。

decrypt_access_token将返回包含解密ClaimsSet的结果。verify_access_token将返回一个空的结果,表示令牌已成功验证——一个Err表示失败。

从访问令牌中提取头部

无论令牌是已签名、加密还是MAC标记,您都可以使用 get_token_headers 提取其头部信息,它将返回一个包含未受保护和受保护头部信息的选项(或者,如果令牌无效,则返回 None)。

COSE 密码

如前所述,加密函数不在此包的范围内。因此,存在各种 COSE 密码特质,包括 CoseEncryptCipherCoseSignCipherCoseMacCipher,每个特质都实现了一个在 RFC 8152 的第 4、5 和 6 节中指定的对应 COSE 操作。还有 MultipleEncryptCipherMultipleSignCipherMultipleMacCipher 特质,这些特质用于创建旨在发送给多个接收者的令牌。

请注意,这些密码不需要将结果包装在,例如,一个 Cose_Encrypt0 结构中,因为这个部分已经由这个库处理(该库使用 coset)——只需实现加密算法本身即可(例如,RFC 8152 的第 5.3 节中“如何解密消息”的第 4 步)。

在实现任何特定的 COSE 密码时,您还需要指定密钥的类型(它必须可转换为 CoseKey),并实现一个设置令牌头部的方法,例如,使用的算法、密钥 ID、IV 等。

变更日志

您可以在 CHANGELOG.md 中找到更改列表。

许可

根据您的选择,许可如下:

贡献

除非您明确声明,否则您提交的任何贡献,按照 Apache-2.0 许可证定义,将按上述方式双许可,无需任何额外的条款或条件。

维护者

该项目目前由以下开发人员维护:

姓名 电子邮件地址 GitHub 用户名
Falko Galperin [email protected] @falko17
Hugo Hakim Damer [email protected] @pulsastrix

依赖

~3.5MB
~78K SLoC