4 个版本

0.2.9 2024年8月8日
0.2.8 2024年8月5日
0.2.7 2024年7月18日
0.2.6 2024年6月3日

#220 in 认证

Download history 153/week @ 2024-05-30 31/week @ 2024-06-06 8/week @ 2024-06-13 18/week @ 2024-06-20 4/week @ 2024-07-11 114/week @ 2024-07-18 7/week @ 2024-07-25 106/week @ 2024-08-01 152/week @ 2024-08-08

379 每月下载
用于 msal

LGPL-3.0-or-later

255KB
6K SLoC

MSAL

本项目的目的是基于 Microsoft API 参考(ClientApplication 类PublicClientApplication 类)实现 MSAL,这些是 Python 参考,在这里将模仿 Rust 实现。

注意:目前本项目不针对ConfidentialClientApplication 类进行实现。如果您有兴趣志愿实现 ConfidentialClientApplication 类,请与维护者联系。

该项目还实现了微软未文档化的[MS-DRS]协议。作为 himmelblau 项目的组成部分,正在进行协议规范的工作。

除了 ClientApplication 类和 [MS-DRS] 实现,该项目还实现了 [MS-OAPXBC] 部分 3.1.5.1.2 请求主刷新令牌3.1.5.1.3 交换主刷新令牌以获取访问令牌。这些在 Microsoft 的 MSAL 库中没有实现,但在从注册设备进行认证时是可能的。

我如何使用这个库?

将模块导入您的项目,然后包含 PublicClientApplication

use msal::PublicClientApplication;

创建 PublicClientApplication 的实例,然后进行认证

let authority = format!("https://login.microsoftonline.com/{}", tenant_id);
let app = PublicClientApplication::new(client_id, Some(&authority)).expect("Failed creating app");
let scope = vec![];
let token = app.acquire_token_by_username_password(username, password, scope).await?;

您可以从 Azure 门户获取您的 client_idtenant_id

您可以使用之前获取的刷新令牌进行静默认证

let token = app.acquire_token_silent(scope, &token.refresh_token).await?;

或者,最后,您可以执行设备授权授予

let flow = app.initiate_device_flow(scope).await?;

// Prompt the user with the message found in flow.message

let token = app.acquire_token_by_device_flow(flow).await?;

如果 msal 使用 broker 功能构建,您可以注册设备,然后请求认证令牌

use kanidm_hsm_crypto::soft::SoftTpm;
use kanidm_hsm_crypto::{BoxedDynTpm, Tpm, AuthValue};

// First create the TPM object and a machine_key
let mut tpm = BoxedDynTpm::new(SoftTpm::new());
let auth_str = AuthValue::generate().expect("Failed to create hex pin");
let auth_value = AuthValue::from_str(&auth_str).expect("Unable to create auth value");
let loadable_machine_key = tpm
    .machine_key_create(&auth_value)
    .expect("Unable to create new machine key");
let machine_key = tpm
    .machine_key_load(&auth_value, &loadable_machine_key)
    .expect("Unable to load machine key");

let app = BrokerClientApplication::new(Some(&authority), None, None).expect("Failed creating app");

// Obtain a token for authentication. If authenticating here without MFA, the PRT and
// user token will not have the mfa claim. Use initiate_device_flow_for_device_enrollment()
// and acquire_token_by_device_flow() to authenticate with the
// mfa claim.
let token = app.acquire_token_by_username_password_for_device_enrollment(username, password).await?;
// Specify the attributes which will be used for enrollment
let attrs = match EnrollAttrs::new(
    domain.to_string(),
    Some("test_machine".to_string()), // Device name
    Some("Linux".to_string()), // Device type
    Some(0), // Join type
    Some("openSUSE Leap 15.5".to_string()), // OS version
) {
    Ok(attrs) => attrs,
    Err(e) => {
        println!("{:?}", e);
        return ();
    }
};
// Use the tpm for enrollment.
let (transport_key, cert_key, device_id) = app.enroll_device(&token.refresh_token, attrs, &mut tpm, &machine_key).await?;

// Request an authentication token
let token = app.acquire_token_by_username_password(username, password, scope, &mut tpm, &machine_key).await?;

为了初始化之前已注册的BrokerClientApplication,请确保您已缓存以下值:auth_valueloadable_machine_keytransport_keycert_keyauth_value 必须以安全的方式存储,只有您的应用程序可以访问。最好您的应用程序以唯一用户身份运行,并且只有该用户可以读取 auth_value。按以下方式重新初始化:

let mut tpm = BoxedDynTpm::new(SoftTpm::new());
let loadable_machine_key = tpm
    .machine_key_create(&auth_value)
    .expect("Unable to create new machine key");
let machine_key = tpm
    .machine_key_load(&auth_value, &loadable_machine_key)
    .expect("Unable to load machine key");

let app = BrokerClientApplication::new(Some(&authority), Some(&transport_key), Some(&cert_key)).expect("Failed creating app");

依赖项

~13–47MB
~769K SLoC