# 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 ```rs 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(), }; ``` #### 1.1 Get Device Access Token ```rs // Reuse the `openid_client` from the previous example let openid_client = OpenIdconnectClient { ... }; let device_access_token = openid_client.request_device_access_token().await; ``` ### 2.0 CIBA Authenticate with user username (OnesID). #### 2.1 Make CIBA Request ```rs // 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)) ``` #### 2.2 Check CIBA Status ```rs // 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: ```rs // Reuse the `openid_client` from the previous example let openid_client = OpenIdconnectClient { ... }; openid_client.validate_token(&id_token).await; ``` ## Guix ```bash guix shell rust-cargo rust gcc-toolchain pkg-config openssl export OPENSSL_DIR=$(dirname $(dirname $(realpath $(which openssl)))) CC=gcc cargo build ```