#macaroon #authorization #cookies #credentials

macaroon-asml-fork

在Rust中实现macaroons的完整功能

1个不稳定版本

0.1.0 2022年12月28日

#357 in 认证

MIT许可证

97KB
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
  • 验证第一方和第三方规避措施(后者使用释放玛卡龙)

示例

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个月内刚刚稳定发布的语言特性或语法。

贡献

我们欢迎任何贡献。任何使事情更简单或更符合惯例的修复也非常受欢迎。如果您有什么想要贡献的内容,请发起一个拉取请求。随着项目的成熟,我们将添加一个更详细的贡献者指南。

依赖关系

~2–3MB
~59K SLoC