Skip to content

Commit 17f4cb6

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 b85c92e commit 17f4cb6

6 files changed

Lines changed: 37 additions & 33 deletions

File tree

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,17 @@ $ git submodule update --init
6767
The basic ceremony examples (register + authenticate) cover all transports. The
6868
WebAuthn examples consume and emit JSON per the [WebAuthn IDL][webauthn].
6969

70-
| Transport | FIDO U2F | WebAuthn (FIDO2) |
71-
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
72-
| **USB (HID)** | `cargo run --example u2f_hid` | `cargo run --example webauthn_hid` |
73-
| **Bluetooth (BLE)** | `cargo run --example u2f_ble` ||
74-
| **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` |
75-
| **Hybrid (caBLE v2)** || `cargo run --example webauthn_cable` |
70+
| Transport | FIDO U2F | WebAuthn (FIDO2) [^ro] |
71+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72+
| **USB (HID)** | `cargo run --example u2f_hid` | `cargo run --features related-origins-client --example webauthn_hid` |
73+
| **Bluetooth (BLE)** | `cargo run --example u2f_ble` | |
74+
| **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` |
75+
| **Hybrid (caBLE v2)** || `cargo run --features related-origins-client --example webauthn_cable` |
7676

7777
[^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.
7878

79+
[^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.
80+
7981
Additional HID-only examples cover specific FIDO2 features and authenticator management:
8082

8183
```

libwebauthn/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,17 @@ required-features = ["nfc"]
125125
[[example]]
126126
name = "webauthn_hid"
127127
path = "examples/ceremony/webauthn_hid.rs"
128+
required-features = ["related-origins-client"]
128129

129130
[[example]]
130131
name = "webauthn_nfc"
131132
path = "examples/ceremony/webauthn_nfc.rs"
132-
required-features = ["nfc"]
133+
required-features = ["nfc", "related-origins-client"]
133134

134135
[[example]]
135136
name = "webauthn_cable"
136137
path = "examples/ceremony/webauthn_cable.rs"
138+
required-features = ["related-origins-client"]
137139

138140
[[example]]
139141
name = "webauthn_extensions_hid"

libwebauthn/examples/ceremony/webauthn_cable.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use qrcode::QrCode;
1212
use tokio::time::sleep;
1313

1414
use libwebauthn::ops::webauthn::{
15-
GetAssertionRequest, JsonFormat, MakeCredentialRequest, NoRelatedOriginsClient, RequestOrigin,
16-
SystemPublicSuffixList, WebAuthnIDL as _, WebAuthnIDLResponse as _,
15+
GetAssertionRequest, JsonFormat, MakeCredentialRequest, RequestOrigin,
16+
ReqwestRelatedOriginsClient, SystemPublicSuffixList, WebAuthnIDL as _,
17+
WebAuthnIDLResponse as _,
1718
};
1819
use libwebauthn::transport::{Channel as _, Device};
1920
use libwebauthn::webauthn::WebAuthn;
@@ -69,6 +70,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
6970
let psl = SystemPublicSuffixList::auto().expect(
7071
"PSL not available; install the publicsuffix-list (or publicsuffix-list-dafsa) package, or pass an explicit path",
7172
);
73+
let related_origins = ReqwestRelatedOriginsClient::new()?;
7274

7375
{
7476
let mut device: CableQrCodeDevice = CableQrCodeDevice::new_persistent(
@@ -94,7 +96,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
9496
let request = MakeCredentialRequest::from_json(
9597
&request_origin,
9698
&psl,
97-
&NoRelatedOriginsClient,
99+
&related_origins,
98100
MAKE_CREDENTIAL_REQUEST,
99101
)
100102
.await
@@ -131,7 +133,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
131133
let request = GetAssertionRequest::from_json(
132134
&request_origin,
133135
&psl,
134-
&NoRelatedOriginsClient,
136+
&related_origins,
135137
GET_ASSERTION_REQUEST,
136138
)
137139
.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
@@ -40,6 +40,8 @@ pub use related_origins::{
4040
validate_related_origins, NoRelatedOriginsClient, RelatedOriginsError,
4141
RelatedOriginsHttpClient, WellKnownResponse,
4242
};
43+
#[cfg(feature = "related-origins-client")]
44+
pub use related_origins::{HttpPolicy, ReqwestRelatedOriginsClient};
4345
use serde::Deserialize;
4446

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

0 commit comments

Comments
 (0)