ones-oidc

Crates.ioones-oidc
lib.rsones-oidc
version0.3.2
created_at2025-01-31 21:13:45.662102+00
updated_at2025-08-09 22:39:46.75061+00
descriptionONES OpenID Connect client for Rust
homepagehttps://ones-now.com/
repositoryhttps://ones-now.com/
max_upload_size
id1537839
size168,125
Franz Geffke (franzos)

documentation

README

ONES OIDC Rust Authentication Library

Package to authenticate with ONES using OpenID Connect (OIDC) and Client Initiated Backchannel Authentication (CIBA).

Usage

1.0 Device Authentication

use ones_oidc::{OpenIdconnectClient, load_device_config, read_private_key, OnesOidcConfig};
use openidconnect::{ClientId, IssuerUrl, core::CoreProviderMetadata, reqwest::async_http_client};

let device_config = load_device_config("./device.yml").expect("Failed to load device config");
let private_key = read_private_key("./device.key").expect("Failed to load private key");

let client_id = device_config.client_id.clone();
let issuer_url = device_config.get_issuer_url().expect("Failed to get issuer URL");

let provider_metadata = CoreProviderMetadata::discover_async(
    issuer_url.clone(),
    async_http_client,
)
.await
.expect("Failed to discover OIDC metadata");

// Create client with default configuration
let openid_client = OpenIdconnectClient::new(
    client_id,
    issuer_url,
    provider_metadata,
    private_key,
);

// Or create client with custom configuration
let config = OnesOidcConfig::default();
let openid_client = OpenIdconnectClient::with_config(
    client_id,
    issuer_url,
    provider_metadata,
    private_key,
    config,
);

1.1 Get Device Access Token

// Reuse the `openid_client` from the previous example
let device_access_token = openid_client.device_access_token().await
    .expect("Failed to get device access token");

// Or use the non-cached version
let device_access_token = openid_client.request_device_access_token().await
    .expect("Failed to request device access token");

2.0 CIBA

Authenticate with user username (OnesID).

2.1 Make CIBA Request

use ones_oidc::{LoginHint, LoginHintKind};

// Reuse the `openid_client` from the previous example
let login_hint = LoginHint {
    kind: LoginHintKind::LoginHint,
    value: "user@example.com".to_string(),
};

let result = openid_client.make_ciba_request(
    &login_hint,
    "openid offline_access profile",
    "Authorize login to Example.com?",
    Some("https://example.com".to_string()),
    None, // qr_session_id
).await;

match result {
    Ok(ciba_response) => {
        println!("CIBA request successful: {:?}", ciba_response);
        // Use ciba_response.auth_req_id for status polling
    }
    Err(e) => {
        eprintln!("CIBA request failed: {}", e);
    }
}

2.2 Check CIBA Status

use ones_oidc::OidcError;

// Reuse the `openid_client` from the previous example
// Use the auth_req_id from the previous CIBA request
let auth_request_id = "your-auth-request-id";

match openid_client.check_ciba_status(auth_request_id).await {
    Ok(ciba_status) => {
        println!("CIBA Status: {:?}", ciba_status);
        // Process the successful response
        if let Some(access_token) = &ciba_status.access_token {
            println!("Access token received: {}", access_token.secret());
        }
    }
    Err(OidcError::CibaAuthenticationPending) => {
        println!("Authorization pending - user hasn't approved yet");
        // Continue polling
    }
    Err(e) => {
        eprintln!("CIBA status check failed: {}", e);
    }
}

3.0 Token Validation

// Reuse the `openid_client` from the previous example
let token = "your-jwt-or-opaque-token";

match openid_client.validate_token(&token, None).await {
    Ok(auth_result) => {
        println!("Token is valid!");
        println!("Subject: {}", auth_result.sub);
        println!("Issuer: {}", auth_result.iss);
        if let Some(username) = &auth_result.username {
            println!("Username: {}", username);
        }
    }
    Err(e) => {
        eprintln!("Token validation failed: {}", e);
    }
}

CLI Tool

The library includes a CLI tool for common operations:

Installation

Build the CLI tool:

cargo build --release --bin cli

Usage

Get Device Access Token

./target/release/cli device access-token

Show Device Configuration

./target/release/cli device config

Query Well-Known Application

./target/release/cli well-known <client-identifier>

Custom Configuration Paths

./target/release/cli --device-config /path/to/device.yml --device-private-key /path/to/key.pem device access-token

Help

./target/release/cli help
./target/release/cli device help
Commit count: 0

cargo fmt