#authorization #cookies #credentials

macaroon

Rust中对macaroons的完整功能实现

2个不稳定版本

0.3.0 2022年10月13日
0.2.0 2021年9月24日
0.1.2 2020年9月22日
0.1.1 2017年2月23日
0.1.0 2017年2月20日

#244 in 身份验证

MIT许可证

94KB
2K SLoC

Ferris holding French macaroons

macaroon

Rust实现的macaroons

Crates.io Build Status codecov Docs.rs

注意:此库不应被视为安全,因此在使用前应通过全面的安全审计。API也可能在0.X次要版本之间有破坏性更改,因此不应被视为稳定。

什么是Macaroons?

Macaroons是载体令牌(类似于cookies),它们在其内部编码了授权可以发生的条件(称为“限制条件”)。例如,授权可以限制为特定用户、账户、一天中的时间等。这些条件可以是本地评估的(称为“第一方限制条件”),或者使用第三方生成的特殊macaroons(称为“释放macaroons”)进行评估(称为“第三方限制条件”)。

第一方限制条件由一个谓词组成,当评估为真时,授权该限制条件。谓词是一个字符串,可以通过严格字符串比较(satisfy_exact)评估,或者使用提供的函数(satisfy_general)进行解释。

第三方限制条件由一个位置字符串、一个标识符和一个用于验证生成的释放macaroons的特殊签名密钥组成。密钥和标识符传递给第三方,第三方生成释放macaroons。接收者然后将每个释放macaroon绑定到原始macaroon。

在验证第三方限制条件期间,从接收到的macaroons中找到一个标识符与限制条件匹配的释放macaroon。验证绑定签名,并使用与原始macaroon相同的过程验证释放macaroon的限制条件。

只有当所有限制条件都通过上述过程授权时,macaroon才被认为是授权的。

实现的功能

  • 创建macaroons,并添加第一方和第三方限制条件
  • 序列化 - 支持1、2和2J版本
  • 验证(主要用于验证反序列化的macaroons)
  • 创建释放macaroons
  • 验证第一方和第三方限制条件(后者使用释放macaroons)

示例

use macaroon::{Macaroon, Verifier, MacaroonKey};

// Initialize to make crypto primitives thread-safe
macaroon::initialize().unwrap(); // Force panic if initialization fails

// Create our key
let key = MacaroonKey::generate(b"key");

// Create our macaroon. A location is optional.
let mut macaroon = match Macaroon::create(Some("location".into()), &key, "id".into()) {
    Ok(macaroon) => macaroon,
    Err(error) => panic!("Error creating macaroon: {:?}", error),
};

// Add our first-party caveat. We say that only someone with account 12345678
// is authorized to access whatever the macaroon is protecting
// Note that we can add however many of these we want, with different predicates
macaroon.add_first_party_caveat("account = 12345678".into());

// Now we verify the macaroon
// First we create the verifier
let mut verifier = Verifier::default();

// We assert that the account number is "12345678"
verifier.satisfy_exact("account = 12345678".into());

// Now we verify the macaroon. It should return `Ok(true)` if the user is authorized
match verifier.verify(&macaroon, &key, Default::default()) {
    Ok(_) => println!("Macaroon verified!"),
    Err(error) => println!("Error validating macaroon: {:?}", error),
}

// Now, let's add a third-party caveat, which just says that we need our third party
// to authorize this for us as well.

// Create a key for the third party caveat
let other_key = MacaroonKey::generate(b"different key");

macaroon.add_third_party_caveat("https://auth.mybank", &other_key, "caveat id".into());

// When we're ready to verify a third-party caveat, we use the location
// (in this case, "https://auth.mybank") to retrieve the discharge macaroons we use to verify.
// These would be created by the third party like so:
let mut discharge = match Macaroon::create(Some("http://auth.mybank/".into()),
                                           &other_key,
                                           "caveat id".into()) {
    Ok(discharge) => discharge,
    Err(error) => panic!("Error creating discharge macaroon: {:?}", error),
};
// And this is the criterion the third party requires for authorization
discharge.add_first_party_caveat("account = 12345678".into());

// Once we receive the discharge macaroon, we bind it to the original macaroon
macaroon.bind(&mut discharge);

// Then we can verify using the same verifier (which will verify both the existing
// first-party caveat and the third party one)
match verifier.verify(&macaroon, &key, vec![discharge]) {
    Ok(_) => println!("Macaroon verified!"),
    Err(error) => println!("Error validating macaroon: {:?}", error),
}

向下兼容

由于原始项目目前仅以小版本发布,我们预计将对API进行破坏性更改,尤其是在我们开始将其应用于更多实际场景时。然而,所有这些更改都将列在每个版本的更改日志和发布说明中。一旦我们找到一个合理且稳定的API,我们将发布1.0版本,此后,所有1.X线的版本都将按照semver进行向后兼容。

最低支持的Rust版本

此包支持Rust语言2021版,目前致力于与稳定版Rust 1.56及以后版本协同工作。它需要std

未来,它应支持Rust的每个稳定版本,并在任何给定时间保持与过去6个月左右发布的Rust稳定版本的兼容性。换句话说,它不会依赖于过去6个月内刚刚稳定发布的语言特性或语法。

贡献

我们欢迎任何贡献。任何使事情更简单或更符合惯例的修复都同样受欢迎。如果您有任何想要贡献的内容,请提交一个pull request。随着项目的成熟,我们将添加更详细的贡献指南。

依赖项

~19MB
~112K SLoC