Generate & return webauthn registration challenge
This commit is contained in:
77
src/data/webauthn_manager.rs
Normal file
77
src/data/webauthn_manager.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web;
|
||||
use webauthn_rs::{RegistrationState, Webauthn, WebauthnConfig};
|
||||
use webauthn_rs::proto::CreationChallengeResponse;
|
||||
|
||||
use crate::constants::APP_NAME;
|
||||
use crate::data::app_config::AppConfig;
|
||||
use crate::data::crypto_wrapper::CryptoWrapper;
|
||||
use crate::data::user::{User, UserID};
|
||||
use crate::utils::err::Res;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WebAuthnAppConfig {
|
||||
origin: url::Url,
|
||||
relying_party_id: String,
|
||||
}
|
||||
|
||||
impl WebauthnConfig for WebAuthnAppConfig {
|
||||
fn get_relying_party_name(&self) -> &str {
|
||||
APP_NAME
|
||||
}
|
||||
|
||||
fn get_origin(&self) -> &url::Url {
|
||||
&self.origin
|
||||
}
|
||||
|
||||
fn get_relying_party_id(&self) -> &str {
|
||||
&self.relying_party_id
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegisterKeyRequest {
|
||||
pub opaque_state: String,
|
||||
pub creation_challenge: CreationChallengeResponse,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
struct RegisterKeyOpaqueData {
|
||||
registration_state: RegistrationState,
|
||||
user_id: UserID,
|
||||
}
|
||||
|
||||
pub type WebAuthManagerReq = web::Data<Arc<WebAuthManager>>;
|
||||
|
||||
pub struct WebAuthManager {
|
||||
core: Webauthn<WebAuthnAppConfig>,
|
||||
crypto_wrapper: CryptoWrapper,
|
||||
}
|
||||
|
||||
impl WebAuthManager {
|
||||
pub fn init(conf: &AppConfig) -> Self {
|
||||
Self {
|
||||
core: Webauthn::new(WebAuthnAppConfig {
|
||||
origin: url::Url::parse(&conf.website_origin)
|
||||
.expect("Failed to parse configuration origin!"),
|
||||
relying_party_id: conf.domain_name().to_string(),
|
||||
}),
|
||||
crypto_wrapper: CryptoWrapper::new_random(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_register(&self, user: &User) -> Res<RegisterKeyRequest> {
|
||||
let (creation_challenge, registration_state) = self.core.generate_challenge_register(
|
||||
&user.username,
|
||||
true,
|
||||
)?;
|
||||
|
||||
Ok(RegisterKeyRequest {
|
||||
opaque_state: self.crypto_wrapper.encrypt(&RegisterKeyOpaqueData {
|
||||
registration_state,
|
||||
user_id: user.uid.clone(),
|
||||
})?,
|
||||
creation_challenge,
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user