Crates.io | ones-oidc |
lib.rs | ones-oidc |
version | 0.2.6 |
source | src |
created_at | 2025-01-31 21:13:45.662102+00 |
updated_at | 2025-03-12 15:30:49.240351+00 |
description | ONES OpenID Connect client for Rust |
homepage | https://ones-now.com/ |
repository | https://ones-now.com/ |
max_upload_size | |
id | 1537839 |
size | 56,555 |
Package to authenticate with ONES using OpenID Connect (OIDC) and Client Initiated Backchannel Authentication (CIBA).
use ones_oidc_rust::{OpenIdconnectClient, load_device_config};
let device_config = load_device_config(&device_config_path).expect("Failed to load device config");
let client_id = ClientId::new(device_config.client_id.clone().to_string());
let issuer_url = IssuerUrl::new(device_config.issuer_url.to_string())
.map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Failed to parse issuer URL"))?;
let provider_metadata = CoreProviderMetadata::discover_async(
issuer_url.clone(),
async_http_client,
)
.await
.map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Failed to discover OIDC metadata"))?;
let openid_client = OpenIdconnectClient {
client_id: client_id,
issuer_url: issuer_url,
issuer_jwks: None,
provider_metadata: provider_metadata.clone(),
// read_private_key: you can supply your own implementation here
private_key: read_private_key(&device_config.private_key_path).unwrap(),
};
// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };
let device_access_token = openid_client.request_device_access_token().await;
Authenticate with user username (OnesID).
// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };
let login_hint = LoginHint {
kind: payload.login_hint_kind,
value: payload.user_identifier.clone(),
};
let result = openid_client.make_ciba_request(
&login_hint,
"openid offline_access profile".to_string(),
"Authorize login to Example.com?".to_string(),
Some("https://example.com".to_string())
).await;
if result.is_err() {
let e = result.err().unwrap();
debug!("Error: {}", e);
return Ok(HttpResponse::InternalServerError().finish());
}
let result = result.unwrap();
Ok(HttpResponse::Ok().json(result))
// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };
let ciba_status = openid_client.check_ciba_status(&auth_request_id).await;
if ciba_status.is_err() {
let ciba_status = ciba_status.unwrap_err();
if ciba_status.to_string() == "Authorization pending" {
println!("Authorization pending");
Ok(HttpResponse::BadRequest().json(ciba_status.to_string()))
} else {
println!("Error: {:?}", ciba_status);
Ok(HttpResponse::InternalServerError().json(ciba_status.to_string()))
}
} else {
let ciba_status = ciba_status.unwrap();
println!("CIBA Status: {:?}", ciba_status);
Ok(HttpResponse::Ok().json(ciba_status))
}
Validate token:
// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };
openid_client.validate_token(&id_token).await;
guix shell rust-cargo rust gcc-toolchain pkg-config openssl
export OPENSSL_DIR=$(dirname $(dirname $(realpath $(which openssl))))
CC=gcc cargo build