Skip to content

Commit 12f716a

Browse files
feat(examples): switch webauthn ceremony examples to ReqwestRelatedOriginsClient
Using NoRelatedOriginsClient in the bundled examples taught readers the wrong default. Wire up the reqwest-backed convenience client instead, gate the three webauthn ceremony examples on the related-origins-client feature, and update the README run commands. Also re-exports HttpPolicy and ReqwestRelatedOriginsClient at ops::webauthn so examples import from a single path.
1 parent 8260a13 commit 12f716a

7 files changed

Lines changed: 48 additions & 51 deletions

File tree

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,18 @@ $ git submodule update --init
6868
The basic ceremony examples (register + authenticate) cover all transports. The
6969
WebAuthn examples consume and emit JSON per the [WebAuthn IDL][webauthn].
7070

71-
| Transport | FIDO U2F | WebAuthn (FIDO2) |
72-
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
73-
| **USB (HID)** | `cargo run --example u2f_hid` | `cargo run --example webauthn_hid` |
74-
| **Bluetooth (BLE)** | `cargo run --example u2f_ble` | `cargo run --example webauthn_ble` |
75-
| **NFC** [^nfc] | `cargo run --features nfc-backend-pcsc --example u2f_nfc`<br>`cargo run --features nfc-backend-libnfc --example u2f_nfc` | `cargo run --features nfc-backend-pcsc --example webauthn_nfc`<br>`cargo run --features nfc-backend-libnfc --example webauthn_nfc` |
76-
| **Hybrid (caBLE v2 + CTAP 2.3)** || `cargo run --example webauthn_cable` |
77-
| **Hybrid (caBLE v2)** || `cargo run --example webauthn_cable_wss` |
71+
| Transport | FIDO U2F | WebAuthn (FIDO2) [^ro] |
72+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
73+
| **USB (HID)** | `cargo run --example u2f_hid` | `cargo run --features related-origins-client --example webauthn_hid` |
74+
| **Bluetooth (BLE)** | `cargo run --example u2f_ble` | `cargo run --features related-origins-client --example webauthn_ble` |
75+
| **NFC** [^nfc] | `cargo run --features nfc-backend-pcsc --example u2f_nfc`<br>`cargo run --features nfc-backend-libnfc --example u2f_nfc` | `cargo run --features nfc-backend-pcsc,related-origins-client --example webauthn_nfc`<br>`cargo run --features nfc-backend-libnfc,related-origins-client --example webauthn_nfc` |
76+
| **Hybrid (caBLE v2 + CTAP 2.3)** | | `cargo run --features related-origins-client --example webauthn_cable` |
77+
| **Hybrid (caBLE v2)** || `cargo run --features related-origins-client --example webauthn_cable_wss` |
7878

7979
[^nfc]: `nfc-backend-pcsc` is pure userspace and recommended on most systems. `nfc-backend-libnfc` requires the `libnfc` system library. Both can be enabled together; the first FIDO device found by either backend is used.
8080

81+
[^ro]: The WebAuthn ceremony examples wire up the bundled reqwest-backed [related-origins](https://www.w3.org/TR/webauthn-3/#sctn-related-origins) client, which lives behind the optional `related-origins-client` feature. Consumers that already ship their own HTTP stack can implement `RelatedOriginsHttpClient` directly and omit the feature.
82+
8183
Additional HID-only examples cover specific FIDO2 features and authenticator management:
8284

8385
```

libwebauthn/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,23 +126,27 @@ required-features = ["nfc"]
126126
[[example]]
127127
name = "webauthn_hid"
128128
path = "examples/ceremony/webauthn_hid.rs"
129+
required-features = ["related-origins-client"]
129130

130131
[[example]]
131132
name = "webauthn_ble"
132133
path = "examples/ceremony/webauthn_ble.rs"
134+
required-features = ["related-origins-client"]
133135

134136
[[example]]
135137
name = "webauthn_nfc"
136138
path = "examples/ceremony/webauthn_nfc.rs"
137-
required-features = ["nfc"]
139+
required-features = ["nfc", "related-origins-client"]
138140

139141
[[example]]
140142
name = "webauthn_cable"
141143
path = "examples/ceremony/webauthn_cable.rs"
144+
required-features = ["related-origins-client"]
142145

143146
[[example]]
144147
name = "webauthn_cable_wss"
145148
path = "examples/ceremony/webauthn_cable_wss.rs"
149+
required-features = ["related-origins-client"]
146150

147151
[[example]]
148152
name = "webauthn_extensions_hid"

libwebauthn/examples/ceremony/webauthn_ble.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::error::Error;
22

33
use libwebauthn::ops::webauthn::{
4-
DatFilePublicSuffixList, GetAssertionRequest, JsonFormat, MakeCredentialRequest,
5-
NoRelatedOriginsClient, RequestOrigin, WebAuthnIDL as _, WebAuthnIDLResponse as _,
4+
DatFilePublicSuffixList, GetAssertionRequest, JsonFormat, MakeCredentialRequest, RequestOrigin,
5+
ReqwestRelatedOriginsClient, WebAuthnIDL as _, WebAuthnIDLResponse as _,
66
};
77
use libwebauthn::proto::ctap2::Ctap2PublicKeyCredentialDescriptor;
88
use libwebauthn::transport::ble::list_devices;
@@ -52,15 +52,11 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
5252
"attestation": "none"
5353
}
5454
"#;
55+
let related_origins = ReqwestRelatedOriginsClient::new()?;
5556
let make_credentials_request: MakeCredentialRequest =
56-
MakeCredentialRequest::from_json(
57-
&request_origin,
58-
&psl,
59-
&NoRelatedOriginsClient,
60-
request_json,
61-
)
62-
.await
63-
.expect("Failed to parse request JSON");
57+
MakeCredentialRequest::from_json(&request_origin, &psl, &related_origins, request_json)
58+
.await
59+
.expect("Failed to parse request JSON");
6460
println!(
6561
"WebAuthn MakeCredential request: {:?}",
6662
make_credentials_request
@@ -102,14 +98,10 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
10298
}}
10399
"#
104100
);
105-
let get_assertion: GetAssertionRequest = GetAssertionRequest::from_json(
106-
&request_origin,
107-
&psl,
108-
&NoRelatedOriginsClient,
109-
&request_json,
110-
)
111-
.await
112-
.expect("Failed to parse request JSON");
101+
let get_assertion: GetAssertionRequest =
102+
GetAssertionRequest::from_json(&request_origin, &psl, &related_origins, &request_json)
103+
.await
104+
.expect("Failed to parse request JSON");
113105
println!("WebAuthn GetAssertion request: {:?}", get_assertion);
114106

115107
let response = retry_user_errors!(channel.webauthn_get_assertion(&get_assertion)).unwrap();

libwebauthn/examples/ceremony/webauthn_cable.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use qrcode::render::unicode;
1111
use qrcode::QrCode;
1212

1313
use libwebauthn::ops::webauthn::{
14-
DatFilePublicSuffixList, JsonFormat, MakeCredentialRequest, NoRelatedOriginsClient,
15-
RequestOrigin, WebAuthnIDL as _, WebAuthnIDLResponse as _,
14+
DatFilePublicSuffixList, JsonFormat, MakeCredentialRequest, RequestOrigin,
15+
ReqwestRelatedOriginsClient, WebAuthnIDL as _, WebAuthnIDLResponse as _,
1616
};
1717
use libwebauthn::transport::{Channel as _, Device};
1818
use libwebauthn::webauthn::WebAuthn;
@@ -58,6 +58,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
5858
let psl = DatFilePublicSuffixList::from_system_file().expect(
5959
"PSL not available; install the publicsuffix-list package or pass an explicit path",
6060
);
61+
let related_origins = ReqwestRelatedOriginsClient::new()?;
6162

6263
let mut device: CableQrCodeDevice = CableQrCodeDevice::new_transient(
6364
QrCodeOperationHint::MakeCredential,
@@ -82,7 +83,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
8283
let request = MakeCredentialRequest::from_json(
8384
&request_origin,
8485
&psl,
85-
&NoRelatedOriginsClient,
86+
&related_origins,
8687
MAKE_CREDENTIAL_REQUEST,
8788
)
8889
.await

libwebauthn/examples/ceremony/webauthn_hid.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use std::error::Error;
22
use std::time::Duration;
33

44
use libwebauthn::ops::webauthn::{
5-
GetAssertionRequest, JsonFormat, MakeCredentialRequest, NoRelatedOriginsClient, RequestOrigin,
6-
SystemPublicSuffixList, WebAuthnIDL as _, WebAuthnIDLResponse as _,
5+
GetAssertionRequest, JsonFormat, MakeCredentialRequest, RequestOrigin,
6+
ReqwestRelatedOriginsClient, SystemPublicSuffixList, WebAuthnIDL as _,
7+
WebAuthnIDLResponse as _,
78
};
89
use libwebauthn::proto::ctap2::Ctap2PublicKeyCredentialDescriptor;
910
use libwebauthn::transport::hid::list_devices;
@@ -32,6 +33,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
3233
let psl = SystemPublicSuffixList::auto().expect(
3334
"PSL not available; install the publicsuffix-list (or publicsuffix-list-dafsa) package, or pass an explicit path",
3435
);
36+
let related_origins = ReqwestRelatedOriginsClient::new()?;
3537
let request_json = r#"
3638
{
3739
"rp": {
@@ -56,14 +58,10 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
5658
"attestation": "none"
5759
}
5860
"#;
59-
let make_credentials_request: MakeCredentialRequest = MakeCredentialRequest::from_json(
60-
&request_origin,
61-
&psl,
62-
&NoRelatedOriginsClient,
63-
request_json,
64-
)
65-
.await
66-
.expect("Failed to parse request JSON");
61+
let make_credentials_request: MakeCredentialRequest =
62+
MakeCredentialRequest::from_json(&request_origin, &psl, &related_origins, request_json)
63+
.await
64+
.expect("Failed to parse request JSON");
6765
println!(
6866
"WebAuthn MakeCredential request: {:?}",
6967
make_credentials_request
@@ -105,14 +103,10 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
105103
}}
106104
"#
107105
);
108-
let get_assertion: GetAssertionRequest = GetAssertionRequest::from_json(
109-
&request_origin,
110-
&psl,
111-
&NoRelatedOriginsClient,
112-
&request_json,
113-
)
114-
.await
115-
.expect("Failed to parse request JSON");
106+
let get_assertion: GetAssertionRequest =
107+
GetAssertionRequest::from_json(&request_origin, &psl, &related_origins, &request_json)
108+
.await
109+
.expect("Failed to parse request JSON");
116110
println!("WebAuthn GetAssertion request: {:?}", get_assertion);
117111

118112
let response = retry_user_errors!(channel.webauthn_get_assertion(&get_assertion)).unwrap();

libwebauthn/examples/ceremony/webauthn_nfc.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::error::Error;
22

33
use libwebauthn::ops::webauthn::{
4-
GetAssertionRequest, JsonFormat, MakeCredentialRequest, NoRelatedOriginsClient, RequestOrigin,
5-
SystemPublicSuffixList, WebAuthnIDL as _, WebAuthnIDLResponse as _,
4+
GetAssertionRequest, JsonFormat, MakeCredentialRequest, RequestOrigin,
5+
ReqwestRelatedOriginsClient, SystemPublicSuffixList, WebAuthnIDL as _,
6+
WebAuthnIDLResponse as _,
67
};
78
use libwebauthn::transport::nfc::{get_nfc_device, is_nfc_available};
89
use libwebauthn::transport::{Channel as _, Device};
@@ -30,10 +31,11 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
3031
let psl = SystemPublicSuffixList::auto().expect(
3132
"PSL not available; install the publicsuffix-list (or publicsuffix-list-dafsa) package, or pass an explicit path",
3233
);
34+
let related_origins = ReqwestRelatedOriginsClient::new()?;
3335
let make_credentials_request = MakeCredentialRequest::from_json(
3436
&request_origin,
3537
&psl,
36-
&NoRelatedOriginsClient,
38+
&related_origins,
3739
r#"
3840
{
3941
"rp": {
@@ -79,7 +81,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
7981
let get_assertion = GetAssertionRequest::from_json(
8082
&request_origin,
8183
&psl,
82-
&NoRelatedOriginsClient,
84+
&related_origins,
8385
r#"
8486
{
8587
"challenge": "Y3JlZGVudGlhbHMtZm9yLWxpbnV4L2xpYndlYmF1dGhu",

libwebauthn/src/ops/webauthn/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub use related_origins::{
4141
validate_related_origins, NoRelatedOriginsClient, RelatedOriginsError,
4242
RelatedOriginsHttpClient, WellKnownResponse,
4343
};
44+
#[cfg(feature = "related-origins-client")]
45+
pub use related_origins::{HttpPolicy, ReqwestRelatedOriginsClient};
4446
use serde::Deserialize;
4547

4648
#[derive(Debug, Clone, Copy, Deserialize, PartialEq)]

0 commit comments

Comments
 (0)