webauthn_rp

Struct AuthenticationClientState

Source
pub struct AuthenticationClientState<'rp_id, 'prf>(/* private fields */);
Expand description

Container of a PublicKeyCredentialRequestOptions that has been used to start the authentication ceremony. This gets sent to the client ASAP.

Implementations§

Source§

impl AuthenticationClientState<'_, '_>

Source

pub const fn options(&self) -> &PublicKeyCredentialRequestOptions<'_, '_>

Returns the PublicKeyCredentialRequestOptions that was used to start an authentication ceremony.

§Examples
assert!(
    PublicKeyCredentialRequestOptions::passkey(&RpId::Domain(AsciiDomain::try_from("example.com".to_owned())?))
        .start_ceremony()?
        .1
        .options()
        .allow_credentials
        .as_ref()
        .is_empty()
);

Trait Implementations§

Source§

impl<'rp_id, 'prf> Debug for AuthenticationClientState<'rp_id, 'prf>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Serialize for AuthenticationClientState<'_, '_>

Available on crate feature serde only.
Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serializes self to conform with PublicKeyCredentialRequestOptionsJSON.

§Examples
/// Retrieves the `AuthTransports` associated with the unique `cred_id`
/// from the database.
fn get_transports(cred_id: CredentialId<&[u8]>) -> Result<AuthTransports, DecodeAuthTransportsErr> {
    // ⋮
}
let mut creds = AllowedCredentials::with_capacity(1);
// `CredentialId::try_from` only exists when `custom` is enabled; and even then, it is
// likely never needed since the `CredentialId` was originally sent from the client and is likely
// stored in a database which would be fetched by `UserHandle` or `Authentication::raw_id`.
let id = CredentialId::try_from(vec![0; 16])?;
let transports = get_transports((&id).into())?;
creds.push(AllowedCredential {
    credential: PublicKeyCredentialDescriptor { id, transports },
    extension: CredentialSpecificExtension {
        prf: Some(PrfInputOwned {
            first: vec![2; 6],
            second: Some(vec![3; 2]),
            ext_info: ExtensionReq::Require,
        }),
    },
});
let rp_id = RpId::Domain(AsciiDomain::try_from("example.com".to_owned())?);
let mut options = PublicKeyCredentialRequestOptions::second_factor(&rp_id, creds)?;
options.hints = Hint::SecurityKey;
// This is actually useless since `CredentialSpecificExtension` takes priority
// when the client receives the payload. We set it for illustration purposes only.
// If `creds` contained an `AllowedCredential` that didn't set
// `CredentialSpecificExtension::prf`, then this would be used for it.
options.extensions = Extension {
    prf: Some(PrfInput {
        first: [0; 4].as_slice(),
        second: None,
        ext_info: ExtensionReq::Require,
    }),
};
// Since we are requesting the PRF extension, we must require user verification; otherwise
// `PublicKeyCredentialRequestOptions::start_ceremony` would error.
options.user_verification = UserVerificationRequirement::Required;
let client_state = serde_json::to_string(&options.start_ceremony()?.1).unwrap();
let json = serde_json::json!({
    "challenge":"AAAAAAAAAAAAAAAAAAAAAA",
    "timeout":300000,
    "rpId":"example.com",
    "allowCredentials":[
        {
            "type":"public-key",
            "id":"AAAAAAAAAAAAAAAAAAAAAA",
            "transports":["usb"]
        }
    ],
    "userVerification":"required",
    "hints":[
        "security-key"
    ],
    "extensions":{
        "prf":{
            "eval":{
                "first":"AAAAAA"
            },
            "evalByCredential":{
                "AAAAAAAAAAAAAAAAAAAAAA":{
                    "first":"AgICAgIC",
                    "second":"AwM"
                }
            }
        }
    }
}).to_string();
// Since `Challenge`s are randomly generated, we don't know what it will be; thus
// we test the JSON string for everything except it.
assert_eq!(client_state.get(..14), json.get(..14));
assert_eq!(client_state.get(36..), json.get(36..));

Auto Trait Implementations§

§

impl<'rp_id, 'prf> Freeze for AuthenticationClientState<'rp_id, 'prf>

§

impl<'rp_id, 'prf> RefUnwindSafe for AuthenticationClientState<'rp_id, 'prf>

§

impl<'rp_id, 'prf> Send for AuthenticationClientState<'rp_id, 'prf>

§

impl<'rp_id, 'prf> Sync for AuthenticationClientState<'rp_id, 'prf>

§

impl<'rp_id, 'prf> Unpin for AuthenticationClientState<'rp_id, 'prf>

§

impl<'rp_id, 'prf> UnwindSafe for AuthenticationClientState<'rp_id, 'prf>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T