This library is still in it’s early stages; Below is an excerpt from our documents API to showcase implementation.
1.0 Installation
Add the lbrary to your Cargo.toml file:
[dependencies]
ones-oidc = "0.2.1"
This package is also available on PantherX (or guix, with PantherX channel) as rust-ones-oidc.
Important: You need to register your device with IDP first. You don’t need to have px-device-identity-service running.
2.0 Device Authentication
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(),
};
2.1 Get Device Access Token
// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };
let device_access_token = openid_client.request_device_access_token().await;
3.0 CIBA
Authenticate with user username (OnesID).
3.1 Make CIBA Request
// 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))
3.2 Check CIBA Status
// 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;
4.0 QR
WIP
5.0 Consent API
WIP