From 5edb58b9420ba062665e14d56347ea6a843e65c1 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 6 Dec 2024 02:00:06 +0000 Subject: [PATCH] Sync documentation of main branch --- .../main/config/quarkus-all-config.adoc | 168 +++-- .../config/quarkus-core_quarkus.test.adoc | 21 + .../config/quarkus-security-webauthn.adoc | 147 ++-- ...us-security-webauthn_quarkus.webauthn.adoc | 147 ++-- .../main/guides/getting-started-testing.adoc | 22 +- _versions/main/guides/images/webauthn-1.png | Bin 23018 -> 22503 bytes _versions/main/guides/images/webauthn-2.png | Bin 22562 -> 21815 bytes _versions/main/guides/images/webauthn-4.png | Bin 22314 -> 21876 bytes _versions/main/guides/images/webauthn-5.png | Bin 23498 -> 23029 bytes .../guides/images/webauthn-custom-login.svg | 1 + .../images/webauthn-custom-register.svg | 1 + .../main/guides/images/webauthn-login.svg | 1 + .../main/guides/images/webauthn-register.svg | 1 + .../main/guides/rest-virtual-threads.adoc | 2 +- _versions/main/guides/security-webauthn.adoc | 642 ++++++++++-------- 15 files changed, 743 insertions(+), 410 deletions(-) create mode 100644 _versions/main/guides/images/webauthn-custom-login.svg create mode 100644 _versions/main/guides/images/webauthn-custom-register.svg create mode 100644 _versions/main/guides/images/webauthn-login.svg create mode 100644 _versions/main/guides/images/webauthn-register.svg diff --git a/_generated-doc/main/config/quarkus-all-config.adoc b/_generated-doc/main/config/quarkus-all-config.adoc index 2f498368ad9..cba56674714 100644 --- a/_generated-doc/main/config/quarkus-all-config.adoc +++ b/_generated-doc/main/config/quarkus-all-config.adoc @@ -9950,6 +9950,27 @@ endif::add-copy-button-to-env-var[] |boolean |`false` +a|icon:lock[title=Fixed at build time] [[quarkus-core_quarkus-test-class-orderer]] [.property-path]##link:#quarkus-core_quarkus-test-class-orderer[`quarkus.test.class-orderer`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.test.class-orderer+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +The FQCN of the JUnit `ClassOrderer` to use. If the class cannot be found, it fallbacks to JUnit default behaviour which does not set a `ClassOrderer` at all. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_TEST_CLASS_ORDERER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_TEST_CLASS_ORDERER+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer` + a|icon:lock[title=Fixed at build time] [[quarkus-core_quarkus-test-include-tags]] [.property-path]##link:#quarkus-core_quarkus-test-include-tags[`quarkus.test.include-tags`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.test.include-tags+++[] @@ -84848,26 +84869,26 @@ endif::add-copy-button-to-env-var[] |boolean |`true` -a| [[quarkus-security-webauthn_quarkus-webauthn-origin]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origin[`quarkus.webauthn.origin`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-origins]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origins[`quarkus.webauthn.origins`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.origin+++[] +config_property_copy_button:+++quarkus.webauthn.origins+++[] endif::add-copy-button-to-config-props[] [.description] -- -The origin of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. +The origins of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. If unspecified, this defaults to whatever URI this application is deployed on. This allows more than one value if you want to allow multiple origins. See https://w3c.github.io/webauthn/++#++sctn-related-origins ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGIN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGINS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_ORIGIN+++` +Environment variable: `+++QUARKUS_WEBAUTHN_ORIGINS+++` endif::add-copy-button-to-env-var[] -- -|string -| +|list of string +|`The URI this application is deployed on` a| [[quarkus-security-webauthn_quarkus-webauthn-transports]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-transports[`quarkus.webauthn.transports`]## ifdef::add-copy-button-to-config-props[] @@ -84903,7 +84924,7 @@ endif::add-copy-button-to-config-props[] [.description] -- -The id (or domain name of your server) +The id (or domain name of your server, as obtained from the first entry of `origins` or looking at where this request is being served from) ifdef::add-copy-button-to-env-var[] @@ -84914,7 +84935,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_RELYING_PARTY_ID+++` endif::add-copy-button-to-env-var[] -- |string -| +|`The host name of the first allowed origin, or the host where this application is deployed` a| [[quarkus-security-webauthn_quarkus-webauthn-relying-party-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-relying-party-name[`quarkus.webauthn.relying-party.name`]## ifdef::add-copy-button-to-config-props[] @@ -84963,27 +84984,48 @@ endif::add-copy-button-to-env-var[] a|`platform`, `cross-platform` | -a| [[quarkus-security-webauthn_quarkus-webauthn-require-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-require-resident-key[`quarkus.webauthn.require-resident-key`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-load-metadata]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-load-metadata[`quarkus.webauthn.load-metadata`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.require-resident-key+++[] +config_property_copy_button:+++quarkus.webauthn.load-metadata+++[] endif::add-copy-button-to-config-props[] [.description] -- -Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. +Load the FIDO metadata for verification. See https://fidoalliance.org/metadata/. Only useful for attestations different from `Attestation.NONE`. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_LOAD_METADATA+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++` +Environment variable: `+++QUARKUS_WEBAUTHN_LOAD_METADATA+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` +a| [[quarkus-security-webauthn_quarkus-webauthn-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-resident-key[`quarkus.webauthn.resident-key`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.resident-key+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++` +endif::add-copy-button-to-env-var[] +-- +a|`discouraged`, `preferred`, `required` +|`REQUIRED` + a| [[quarkus-security-webauthn_quarkus-webauthn-user-verification]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-verification[`quarkus.webauthn.user-verification`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.user-verification+++[] @@ -85007,7 +85049,28 @@ Environment variable: `+++QUARKUS_WEBAUTHN_USER_VERIFICATION+++` endif::add-copy-button-to-env-var[] -- a|`required`, `preferred`, `discouraged` -|`DISCOURAGED` +|`REQUIRED` + +a| [[quarkus-security-webauthn_quarkus-webauthn-user-presence-required]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-presence-required[`quarkus.webauthn.user-presence-required`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.user-presence-required+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +User presence requirements. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` a| [[quarkus-security-webauthn_quarkus-webauthn-timeout]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-timeout[`quarkus.webauthn.timeout`]## ifdef::add-copy-button-to-config-props[] @@ -85028,7 +85091,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-all-config[icon:question-circle[title=More information about the Duration format]] -|`60s` +|`5m` a| [[quarkus-security-webauthn_quarkus-webauthn-attestation]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-attestation[`quarkus.webauthn.attestation`]## ifdef::add-copy-button-to-config-props[] @@ -85056,22 +85119,22 @@ endif::add-copy-button-to-env-var[] a|`none`, `indirect`, `direct`, `enterprise` |`NONE` -a| [[quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params[`quarkus.webauthn.pub-key-cred-params`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters[`quarkus.webauthn.public-key-credential-parameters`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.pub-key-cred-params+++[] +config_property_copy_button:+++quarkus.webauthn.public-key-credential-parameters+++[] endif::add-copy-button-to-config-props[] [.description] -- -Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. +Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. See https://www.w3.org/TR/webauthn-1/++#++dictdef-publickeycredentialparameters ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++` +Environment variable: `+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++` endif::add-copy-button-to-env-var[] -- a|list of `es256`, `es384`, `es512`, `ps256`, `ps384`, `ps512`, `es256k`, `rs256`, `rs384`, `rs512`, `rs1`, `ed-dsa` @@ -85203,27 +85266,6 @@ endif::add-copy-button-to-env-var[] |string |`_quarkus_webauthn_challenge` -a| [[quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name[`quarkus.webauthn.challenge-username-cookie-name`]## -ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.challenge-username-cookie-name+++[] -endif::add-copy-button-to-config-props[] - - -[.description] --- -The cookie that is used to store the username data during login/registration - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++` -endif::add-copy-button-to-env-var[] --- -|string -|`_quarkus_webauthn_username` - a| [[quarkus-security-webauthn_quarkus-webauthn-cookie-same-site]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-cookie-same-site[`quarkus.webauthn.cookie-same-site`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.cookie-same-site+++[] @@ -85287,6 +85329,48 @@ endif::add-copy-button-to-env-var[] |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-all-config[icon:question-circle[title=More information about the Duration format]] | +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint[`quarkus.webauthn.enable-registration-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-registration-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default registration endpoint at `/q/webauthn/register`, in which case you should also implement the `WebAuthnUserProvider.store` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint[`quarkus.webauthn.enable-login-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-login-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default login endpoint at `/q/webauthn/login`, in which case you should also implement the `WebAuthnUserProvider.update` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + h|[.extension-name]##SmallRye Fault Tolerance## h|Type diff --git a/_generated-doc/main/config/quarkus-core_quarkus.test.adoc b/_generated-doc/main/config/quarkus-core_quarkus.test.adoc index e7ed91bff62..94924f61c8a 100644 --- a/_generated-doc/main/config/quarkus-core_quarkus.test.adoc +++ b/_generated-doc/main/config/quarkus-core_quarkus.test.adoc @@ -55,6 +55,27 @@ endif::add-copy-button-to-env-var[] |boolean |`false` +a|icon:lock[title=Fixed at build time] [[quarkus-core_quarkus-test-class-orderer]] [.property-path]##link:#quarkus-core_quarkus-test-class-orderer[`quarkus.test.class-orderer`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.test.class-orderer+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +The FQCN of the JUnit `ClassOrderer` to use. If the class cannot be found, it fallbacks to JUnit default behaviour which does not set a `ClassOrderer` at all. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_TEST_CLASS_ORDERER+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_TEST_CLASS_ORDERER+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer` + a|icon:lock[title=Fixed at build time] [[quarkus-core_quarkus-test-include-tags]] [.property-path]##link:#quarkus-core_quarkus-test-include-tags[`quarkus.test.include-tags`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.test.include-tags+++[] diff --git a/_generated-doc/main/config/quarkus-security-webauthn.adoc b/_generated-doc/main/config/quarkus-security-webauthn.adoc index e849ec5b732..51173f93fc5 100644 --- a/_generated-doc/main/config/quarkus-security-webauthn.adoc +++ b/_generated-doc/main/config/quarkus-security-webauthn.adoc @@ -28,26 +28,26 @@ endif::add-copy-button-to-env-var[] |boolean |`true` -a| [[quarkus-security-webauthn_quarkus-webauthn-origin]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origin[`quarkus.webauthn.origin`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-origins]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origins[`quarkus.webauthn.origins`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.origin+++[] +config_property_copy_button:+++quarkus.webauthn.origins+++[] endif::add-copy-button-to-config-props[] [.description] -- -The origin of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. +The origins of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. If unspecified, this defaults to whatever URI this application is deployed on. This allows more than one value if you want to allow multiple origins. See https://w3c.github.io/webauthn/++#++sctn-related-origins ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGIN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGINS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_ORIGIN+++` +Environment variable: `+++QUARKUS_WEBAUTHN_ORIGINS+++` endif::add-copy-button-to-env-var[] -- -|string -| +|list of string +|`The URI this application is deployed on` a| [[quarkus-security-webauthn_quarkus-webauthn-transports]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-transports[`quarkus.webauthn.transports`]## ifdef::add-copy-button-to-config-props[] @@ -83,7 +83,7 @@ endif::add-copy-button-to-config-props[] [.description] -- -The id (or domain name of your server) +The id (or domain name of your server, as obtained from the first entry of `origins` or looking at where this request is being served from) ifdef::add-copy-button-to-env-var[] @@ -94,7 +94,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_RELYING_PARTY_ID+++` endif::add-copy-button-to-env-var[] -- |string -| +|`The host name of the first allowed origin, or the host where this application is deployed` a| [[quarkus-security-webauthn_quarkus-webauthn-relying-party-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-relying-party-name[`quarkus.webauthn.relying-party.name`]## ifdef::add-copy-button-to-config-props[] @@ -143,27 +143,48 @@ endif::add-copy-button-to-env-var[] a|`platform`, `cross-platform` | -a| [[quarkus-security-webauthn_quarkus-webauthn-require-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-require-resident-key[`quarkus.webauthn.require-resident-key`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-load-metadata]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-load-metadata[`quarkus.webauthn.load-metadata`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.require-resident-key+++[] +config_property_copy_button:+++quarkus.webauthn.load-metadata+++[] endif::add-copy-button-to-config-props[] [.description] -- -Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. +Load the FIDO metadata for verification. See https://fidoalliance.org/metadata/. Only useful for attestations different from `Attestation.NONE`. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_LOAD_METADATA+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++` +Environment variable: `+++QUARKUS_WEBAUTHN_LOAD_METADATA+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` +a| [[quarkus-security-webauthn_quarkus-webauthn-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-resident-key[`quarkus.webauthn.resident-key`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.resident-key+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++` +endif::add-copy-button-to-env-var[] +-- +a|`discouraged`, `preferred`, `required` +|`REQUIRED` + a| [[quarkus-security-webauthn_quarkus-webauthn-user-verification]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-verification[`quarkus.webauthn.user-verification`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.user-verification+++[] @@ -187,7 +208,28 @@ Environment variable: `+++QUARKUS_WEBAUTHN_USER_VERIFICATION+++` endif::add-copy-button-to-env-var[] -- a|`required`, `preferred`, `discouraged` -|`DISCOURAGED` +|`REQUIRED` + +a| [[quarkus-security-webauthn_quarkus-webauthn-user-presence-required]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-presence-required[`quarkus.webauthn.user-presence-required`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.user-presence-required+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +User presence requirements. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` a| [[quarkus-security-webauthn_quarkus-webauthn-timeout]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-timeout[`quarkus.webauthn.timeout`]## ifdef::add-copy-button-to-config-props[] @@ -208,7 +250,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-security-webauthn_quarkus-webauthn[icon:question-circle[title=More information about the Duration format]] -|`60s` +|`5m` a| [[quarkus-security-webauthn_quarkus-webauthn-attestation]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-attestation[`quarkus.webauthn.attestation`]## ifdef::add-copy-button-to-config-props[] @@ -236,22 +278,22 @@ endif::add-copy-button-to-env-var[] a|`none`, `indirect`, `direct`, `enterprise` |`NONE` -a| [[quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params[`quarkus.webauthn.pub-key-cred-params`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters[`quarkus.webauthn.public-key-credential-parameters`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.pub-key-cred-params+++[] +config_property_copy_button:+++quarkus.webauthn.public-key-credential-parameters+++[] endif::add-copy-button-to-config-props[] [.description] -- -Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. +Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. See https://www.w3.org/TR/webauthn-1/++#++dictdef-publickeycredentialparameters ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++` +Environment variable: `+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++` endif::add-copy-button-to-env-var[] -- a|list of `es256`, `es384`, `es512`, `ps256`, `ps384`, `ps512`, `es256k`, `rs256`, `rs384`, `rs512`, `rs1`, `ed-dsa` @@ -383,27 +425,6 @@ endif::add-copy-button-to-env-var[] |string |`_quarkus_webauthn_challenge` -a| [[quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name[`quarkus.webauthn.challenge-username-cookie-name`]## -ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.challenge-username-cookie-name+++[] -endif::add-copy-button-to-config-props[] - - -[.description] --- -The cookie that is used to store the username data during login/registration - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++` -endif::add-copy-button-to-env-var[] --- -|string -|`_quarkus_webauthn_username` - a| [[quarkus-security-webauthn_quarkus-webauthn-cookie-same-site]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-cookie-same-site[`quarkus.webauthn.cookie-same-site`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.cookie-same-site+++[] @@ -467,6 +488,48 @@ endif::add-copy-button-to-env-var[] |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-security-webauthn_quarkus-webauthn[icon:question-circle[title=More information about the Duration format]] | +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint[`quarkus.webauthn.enable-registration-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-registration-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default registration endpoint at `/q/webauthn/register`, in which case you should also implement the `WebAuthnUserProvider.store` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint[`quarkus.webauthn.enable-login-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-login-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default login endpoint at `/q/webauthn/login`, in which case you should also implement the `WebAuthnUserProvider.update` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + |=== ifndef::no-duration-note[] diff --git a/_generated-doc/main/config/quarkus-security-webauthn_quarkus.webauthn.adoc b/_generated-doc/main/config/quarkus-security-webauthn_quarkus.webauthn.adoc index e849ec5b732..51173f93fc5 100644 --- a/_generated-doc/main/config/quarkus-security-webauthn_quarkus.webauthn.adoc +++ b/_generated-doc/main/config/quarkus-security-webauthn_quarkus.webauthn.adoc @@ -28,26 +28,26 @@ endif::add-copy-button-to-env-var[] |boolean |`true` -a| [[quarkus-security-webauthn_quarkus-webauthn-origin]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origin[`quarkus.webauthn.origin`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-origins]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-origins[`quarkus.webauthn.origins`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.origin+++[] +config_property_copy_button:+++quarkus.webauthn.origins+++[] endif::add-copy-button-to-config-props[] [.description] -- -The origin of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. +The origins of the application. The origin is basically protocol, host and port. If you are calling WebAuthn API while your application is located at `https://example.com/login`, then origin will be `https://example.com`. If you are calling from `http://localhost:2823/test`, then the origin will be `http://localhost:2823`. Please note that WebAuthn API will not work on pages loaded over HTTP, unless it is localhost, which is considered secure context. If unspecified, this defaults to whatever URI this application is deployed on. This allows more than one value if you want to allow multiple origins. See https://w3c.github.io/webauthn/++#++sctn-related-origins ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGIN+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ORIGINS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_ORIGIN+++` +Environment variable: `+++QUARKUS_WEBAUTHN_ORIGINS+++` endif::add-copy-button-to-env-var[] -- -|string -| +|list of string +|`The URI this application is deployed on` a| [[quarkus-security-webauthn_quarkus-webauthn-transports]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-transports[`quarkus.webauthn.transports`]## ifdef::add-copy-button-to-config-props[] @@ -83,7 +83,7 @@ endif::add-copy-button-to-config-props[] [.description] -- -The id (or domain name of your server) +The id (or domain name of your server, as obtained from the first entry of `origins` or looking at where this request is being served from) ifdef::add-copy-button-to-env-var[] @@ -94,7 +94,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_RELYING_PARTY_ID+++` endif::add-copy-button-to-env-var[] -- |string -| +|`The host name of the first allowed origin, or the host where this application is deployed` a| [[quarkus-security-webauthn_quarkus-webauthn-relying-party-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-relying-party-name[`quarkus.webauthn.relying-party.name`]## ifdef::add-copy-button-to-config-props[] @@ -143,27 +143,48 @@ endif::add-copy-button-to-env-var[] a|`platform`, `cross-platform` | -a| [[quarkus-security-webauthn_quarkus-webauthn-require-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-require-resident-key[`quarkus.webauthn.require-resident-key`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-load-metadata]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-load-metadata[`quarkus.webauthn.load-metadata`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.require-resident-key+++[] +config_property_copy_button:+++quarkus.webauthn.load-metadata+++[] endif::add-copy-button-to-config-props[] [.description] -- -Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. +Load the FIDO metadata for verification. See https://fidoalliance.org/metadata/. Only useful for attestations different from `Attestation.NONE`. ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_LOAD_METADATA+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_REQUIRE_RESIDENT_KEY+++` +Environment variable: `+++QUARKUS_WEBAUTHN_LOAD_METADATA+++` endif::add-copy-button-to-env-var[] -- |boolean |`false` +a| [[quarkus-security-webauthn_quarkus-webauthn-resident-key]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-resident-key[`quarkus.webauthn.resident-key`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.resident-key+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Resident key required. A resident (private) key, is a key that cannot leave your authenticator device, this means that you cannot reuse the authenticator to log into a second computer. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_RESIDENT_KEY+++` +endif::add-copy-button-to-env-var[] +-- +a|`discouraged`, `preferred`, `required` +|`REQUIRED` + a| [[quarkus-security-webauthn_quarkus-webauthn-user-verification]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-verification[`quarkus.webauthn.user-verification`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.user-verification+++[] @@ -187,7 +208,28 @@ Environment variable: `+++QUARKUS_WEBAUTHN_USER_VERIFICATION+++` endif::add-copy-button-to-env-var[] -- a|`required`, `preferred`, `discouraged` -|`DISCOURAGED` +|`REQUIRED` + +a| [[quarkus-security-webauthn_quarkus-webauthn-user-presence-required]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-user-presence-required[`quarkus.webauthn.user-presence-required`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.user-presence-required+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +User presence requirements. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_USER_PRESENCE_REQUIRED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` a| [[quarkus-security-webauthn_quarkus-webauthn-timeout]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-timeout[`quarkus.webauthn.timeout`]## ifdef::add-copy-button-to-config-props[] @@ -208,7 +250,7 @@ Environment variable: `+++QUARKUS_WEBAUTHN_TIMEOUT+++` endif::add-copy-button-to-env-var[] -- |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-security-webauthn_quarkus-webauthn[icon:question-circle[title=More information about the Duration format]] -|`60s` +|`5m` a| [[quarkus-security-webauthn_quarkus-webauthn-attestation]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-attestation[`quarkus.webauthn.attestation`]## ifdef::add-copy-button-to-config-props[] @@ -236,22 +278,22 @@ endif::add-copy-button-to-env-var[] a|`none`, `indirect`, `direct`, `enterprise` |`NONE` -a| [[quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-pub-key-cred-params[`quarkus.webauthn.pub-key-cred-params`]## +a| [[quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-public-key-credential-parameters[`quarkus.webauthn.public-key-credential-parameters`]## ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.pub-key-cred-params+++[] +config_property_copy_button:+++quarkus.webauthn.public-key-credential-parameters+++[] endif::add-copy-button-to-config-props[] [.description] -- -Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. +Allowed Public Key Credential algorithms by preference order. Webauthn mandates that all authenticators must support at least the following 2 algorithms: `ES256` and `RS256`. Applications may require stronger keys and algorithms, for example: `ES512` or `EdDSA`. Note that the use of stronger algorithms, e.g.: `EdDSA` may require Java 15 or a cryptographic `JCE` provider that implements the algorithms. See https://www.w3.org/TR/webauthn-1/++#++dictdef-publickeycredentialparameters ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++[] endif::add-copy-button-to-env-var[] ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_PUB_KEY_CRED_PARAMS+++` +Environment variable: `+++QUARKUS_WEBAUTHN_PUBLIC_KEY_CREDENTIAL_PARAMETERS+++` endif::add-copy-button-to-env-var[] -- a|list of `es256`, `es384`, `es512`, `ps256`, `ps384`, `ps512`, `es256k`, `rs256`, `rs384`, `rs512`, `rs1`, `ed-dsa` @@ -383,27 +425,6 @@ endif::add-copy-button-to-env-var[] |string |`_quarkus_webauthn_challenge` -a| [[quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-challenge-username-cookie-name[`quarkus.webauthn.challenge-username-cookie-name`]## -ifdef::add-copy-button-to-config-props[] -config_property_copy_button:+++quarkus.webauthn.challenge-username-cookie-name+++[] -endif::add-copy-button-to-config-props[] - - -[.description] --- -The cookie that is used to store the username data during login/registration - - -ifdef::add-copy-button-to-env-var[] -Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++[] -endif::add-copy-button-to-env-var[] -ifndef::add-copy-button-to-env-var[] -Environment variable: `+++QUARKUS_WEBAUTHN_CHALLENGE_USERNAME_COOKIE_NAME+++` -endif::add-copy-button-to-env-var[] --- -|string -|`_quarkus_webauthn_username` - a| [[quarkus-security-webauthn_quarkus-webauthn-cookie-same-site]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-cookie-same-site[`quarkus.webauthn.cookie-same-site`]## ifdef::add-copy-button-to-config-props[] config_property_copy_button:+++quarkus.webauthn.cookie-same-site+++[] @@ -467,6 +488,48 @@ endif::add-copy-button-to-env-var[] |link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-quarkus-security-webauthn_quarkus-webauthn[icon:question-circle[title=More information about the Duration format]] | +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-registration-endpoint[`quarkus.webauthn.enable-registration-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-registration-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default registration endpoint at `/q/webauthn/register`, in which case you should also implement the `WebAuthnUserProvider.store` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_REGISTRATION_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + +a| [[quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint]] [.property-path]##link:#quarkus-security-webauthn_quarkus-webauthn-enable-login-endpoint[`quarkus.webauthn.enable-login-endpoint`]## +ifdef::add-copy-button-to-config-props[] +config_property_copy_button:+++quarkus.webauthn.enable-login-endpoint+++[] +endif::add-copy-button-to-config-props[] + + +[.description] +-- +Set to `true` if you want to enable the default login endpoint at `/q/webauthn/login`, in which case you should also implement the `WebAuthnUserProvider.update` method. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_WEBAUTHN_ENABLE_LOGIN_ENDPOINT+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + |=== ifndef::no-duration-note[] diff --git a/_versions/main/guides/getting-started-testing.adoc b/_versions/main/guides/getting-started-testing.adoc index 916b16f57fd..e2c0fac89cc 100644 --- a/_versions/main/guides/getting-started-testing.adoc +++ b/_versions/main/guides/getting-started-testing.adoc @@ -472,24 +472,10 @@ a bit slower, as it adds a shutdown/startup cycle to the test time, but gives a To reduce the amount of times Quarkus needs to restart, `io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer` is registered as a global `ClassOrderer` as described in the link:https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-execution-order-classes[JUnit 5 User Guide]. -The behavior of this `ClassOrderer` is configurable via `junit-platform.properties` (see the source code or javadoc for more details). -It can also be disabled entirely by setting another `ClassOrderer` that is provided by JUnit 5 or even your own custom one. + -Please note that as of JUnit 5.8.2 link:https://github.com/junit-team/junit5/issues/2794[only a single `junit-platform.properties` is picked up and a warning is logged if more than one is found]. -If you encounter such warnings, you can get rid of them by removing the Quarkus-supplied `junit-platform.properties` from the classpath via an exclusion: -[source,xml] ----- - - io.quarkus - quarkus-junit5 - test - - - io.quarkus - quarkus-junit5-properties - - - ----- +The behavior of this `ClassOrderer` is configurable via `application.properties` using the property +`quarkus.test.class-orderer`. The property accepts the FQCN of the `ClassOrderer` to use. If the class cannot be found, +it fallbacks to JUnit default behaviour which does not set a `ClassOrderer` at all. It can also be disabled entirely by +setting another `ClassOrderer` that is provided by JUnit 5 or even your own custom one. === Writing a Profile diff --git a/_versions/main/guides/images/webauthn-1.png b/_versions/main/guides/images/webauthn-1.png index 70b1764e343edb380622ae4f62d1141d6e3d701b..515e71df96b04b50a5d0be6ddbd26506e51017e1 100644 GIT binary patch delta 18692 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 Vn`0--Qw*WO;GocBbpdB{{tfT^u5bVV delta 19154 zcmZU4WmMQqv@P!LPVwUI?oh17o#O7U!QCnD4#nNw9g4fVyTjwVcfDUXS#$o(WHNIy z$?Uz)$zc`fNgZe`IcR4b#W%o#fV(#Ea~H!Aq8zo`zB;V~zkPQKdzdu6KumglmQKl- z2KyUIL@c9$^xkJQ}nV4Tm*U7 zNJ>_{-$fhriLQDi=2X_g(`)hJcn$fa-OvhhSB&Hh+Ixy#nw5=An!cqfTG&x zD;ji_x0M+n5xh$${%5DQg6%dZHju(S z@#ysA6$?Irhdb|a5<%cKn>SluNvYQ1~Iew3^J?YBbP=%0VG zk!ikd z4&};_LLk$RMjRcQ1g5Y*D3Q6C9HLkvJ>8XU&D1b#%9v?vlnQoVxgsSr5fuM9za?I@ zqaa>}TCsla-wyygRv|pJ1n0?FF0G-Y#A3dvqbSX?RIx!-P3xS#5rQj;Qclad;(oFq zGmh8RmFUR3KTd+kczF7kB))gN0P7Ts@kzN&QuMa+pZF-AqiBY1t#}eTB@5w4k&sKr@c&PfgUuc=Q zZ(uYQtDflOjK&e2NvHVVJh5^*tPD Lvclrh-Lnpawf?41LLkL(?+P0~X;r%#E! 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 b4w1LT4+&5)O-@h+%3*rN@^ZD2+n@gebD+5H diff --git a/_versions/main/guides/images/webauthn-2.png b/_versions/main/guides/images/webauthn-2.png index 760faf4a615067ccdfcb8e157695c7a107b5f513..e9522798b0152b6aaded14e845f538fa0a8c8ed2 100644 GIT binary patch delta 18171 zcmce-Wl$V#@Gpu5cL?t8?(PKF1b26L8QdkfEp8#W2Z!KJSlpcu+#L?@zfRpc_sgw1 zU+z@x%^?akl(2wagwM>0UJ-Ej)bsxx6fTL%3F0r$q>^%f`9k# zBde10nV)^zs~Z^hF;k$?qu@(IUe5u?2hwiaWSpNje=O~iY6XrbVo7EE1F8>&2cJ3t z|MboLz-ymhkHTcvYTLSo@5HAbN~HOK;!Stipvu*})NUtG-}5?Hb^bV99=(C|c{9lg zkl4hUyqBWx2~66+s#>f!%_#-~!W?RkpWn3b9#G%DJsq!+rue@Br&226XbMx`)T28y zW(^7H-V7vlUMPgm(}HXBOBFZF9+waxAJstJ{z_;qPR(!5Gp)-{4@Vj;PlEK@ZY{Qf zX!Q9ZYu)<5gU^?%-72BNciVk|4bgqTNt8GCZskw;-{<=-fipKt<$7Dnxzm6jiIgIu z?2e6Ltin)wcJn1L5Wz_%ahGDM{J zVe<1c9qe|!Gj2qg2K8{p#g#mx{uF|I^A32s>cruoBe7sjk~6-yi(x+MQB=*7!i7a# z)M_iKIY)rUP(aElB(SBhtN3C|e+TlDhjIO0Ft|Wp&^aoGIXXt;R@yl-InvG5dUJz3 znf%Ci!EY`@Q_?g$it<&a!S*w70X~M1REW{Uu$i?ONu8IkRMNHU;-{}M^hGi7J?=^r zc_y%!BQK5@8Ok)96hbPYZ=4hv2DvdW=udS1@?$ry&h=XMP*`%f7rt9NhRD}Q1bIH; zTjiDN#Qr8-X*!;%7*B?zuB2J0TCKA=hHBRPU9IKV@tPob{*>J8rP~Aey^1f)3feu6 zrlOq~H4K$^0g6c=zcvBbnt8Vph{SL=_7sS=XS!tO~?YdvzhJY#}rAI^8i> zuph}b zZ1W`8ZL;J|MAV<1u}&LxXP#yF>2bvHogs_?bMbqDU-_7l3p!A}qL20UlTB`G!l;9c zgvUt|;~ZNX_h>T?h9TwxuTwe_Rz0tqXi{SKYYen3%o?=#&Ap{r&p}k_hmn2{KJNfW~4si znWz)?0ZcuioXYGfrW^{&X=42uZke?JL1#>sG*6;8M|Rdqb5)cxqw+ZRqMG;|b4B3g8c zM_^-c!RQ4T2u6~8Sbs!{=O!1|O3&+H#TwY-e&VjC@GS$Wh-V(n%&~D_r^G)iiDHRC zuzBcLFA3r|=2M`8gP>A*u053_QNy101{M)_xq=zNgdUE@>VB|3AlC$mKbwvY!~-2X z1tfGrx%bH#u4tL5+48HslFFY1u^^^NAR!v|USN;-pqCH4>n5!CM#_={yU=w(f=9ue zc+)E-9=AY8v0RDWdn6tjM^}lx= zOXJnlqk~4(d|Cr13Upi9{*DPd2=!nONxvifV}5=-QLPPB8b^p(_U|np4Vk`sXV-aH zTIm6DnfwE$08X6;qNbi)rWZQs|L)ab-z*z0RE}Q2qra!?E@@N3jUZ3GXpwqCS2nYl zUK|l#Y#T0UZ*Lk$f9K;IiYno}mCXWNIuCj)4?;Q*r@muu`kiNW+$_wr|6;~T*js(} zow>ML?1`5QOK>BNzkE$}m*ML-^bl?32CyA=PP0wA>$9yp?iZPiF_wQGw>Yn?yXy1Y zd5Y>El_&5vF|QwZo^7R9Dc=8zkZFk@Je|F;M?vu14b$SglJM-)K&={agW>WwZbI)i z(f+kAs9*-=JW*-wDm{E)&SWh?z`o!>z_-H3UcFy%&3#7h^LL%`Sf*pr52-rJ0jPz^ zxxIwKY~G7VBp^cEXLvva`CkaKGeu~B&1hmAu_=OFzOvS{C%&c|ogB_!42_nojy($} zBfB9;zCXqd9#q^(!bXa(_}Q|nD8S(-`L?4hgPX>C#S^wRcMR)d@$~5gM0mjlH)V#| z7gc0B^NDns>l?q-8S$X-7MTE%3~B1sqGgG`I>VqA}-IsOClM>*JdkBUIpf&332=pkzr=TcJVc ztvQRQvKS^J`_6+{xI8&`vYkhWYr{zAxkGn~Af#7ptss>=za9PhD;teGr-~Bx$7^=r zyW=@LKi!?H3v@#Kftri%Z8K#i?W>-{ zBI-Rk+Hep_n?cE!2jnR^rwcFsD)L3o4&(~3_O>~c0xJ+Vds+CXd9^qZi6p1CW)xB$OT`G8 zdP7dBQs)OY2Z|^NzFowTz>OO|bSk;XEJ^MZrwQ*b9ph|$I%8R#1m!I4Ufo4zV#2CVHZCf}|Y_DV$nHJhHlKyw0a-9w==WU!TAPlWRpZ%gAr zbzQ&1tQ_8Dq^q(B^!6HdXFlqd@VYIpqzWc?IFc@7zax1b*xdO*ah^2hIT$@b%tZ{j z+r|6b@_AoR;V6fygJSoOr-%q@f z{NzQ}n(aeq7!_5gke!^gCgK?x8wtcSugf?eR-x;u6ZlG({2nZtdt7EyF*D9`GI+UZ zfu$cYDx5Iu=BuYH-fSa%6cea?NhF2gd~~oh6ctH(yIb769O;vvQ?k6Eh%uCzf6Wb_ z0;HK?-dlRkggFIj_cwOVeS%kZ8ozT;5>qbQVl;ZF7ZOH?g3uo%rM|LyRM0hvJ}!sI zUX;6;U>@=N4JY3nvVXO)62(%%m6?6Bz#SMF@!n)Da1ZraFGXSl74GYG9EY2Imx;`c z5nhWM^x&#^Kf0~Ne|m0Rd%sQIUgf3_0FYUo8{hzhopR+4w3+gW7af+3BJ7`#&woI9 zKfzww*INgRQbIh(2yHnQTMvovzuz6351#g<0^L!12rkgH+Ea>U$)n>$36BdX91!wVC$MwI7P?WZ>m!MKP&we5;4*5SG^-c`6q}@F0B$Cl zPt6HhOgn_=%Eu#N4)ktgtm;GsX=3XWe2E>jGH&ZZ0PTJ#L$&bQkMkGfTVz@n9M$R% zgr6Zg)8EY`*V#6C9qkb_5iW4@FtV$DMZ(PnK@qU2c>6#@U0Fzuz&>AKhQ;SJMp*%! zu7r0A^P~_||0+7&9UsRFf4elD5kC1d9Oc(;Ye5IzKQ%`8QqR1L2I+-r_O3dsq(GvP z1EuPfsGjI9BdWP4MHIw#pJPu=Y7yEzuA`8FM13vY zm!Y=54ZWQGmNddDL^L?D2379tj9CPi$SzXz?qj$O%-{H(ToxF(7rJQy6S~@3Cb!%J zykzYGOsXhVRZ0BMOHs2wQ%uQ~o)OUAe;j9wlzy*7mPz=eSt#!Lx&>Tx=vA@_1M~8T z)Il4#!;g4yP#t28XMCH(31A_}m+9WLjY};;v6GY=U)fk9NXgaSK@VAtyP$Dmx=8FJyt8PuMpW{ zt}Wm9tW_W&Q1xsywcWLq6a~zj8uQVEpr|Z4__@tEEIF9DxJ}KOx%fDEm`%8N*_e4P z&DkwEI803WI80I`u}bNAIoY}S*!j7*xY+sm`8X*M$;ilL<&;zfzFD}s**G~0Q*f}b zv$1gUq+nq4>Hqhyw}Z2Ql7+j8xrw`pl!?2=2L&4kmjFAv06UlF$C;a7fQ^fhja`6^ z?SHua551GQjit~3H+7>dHZo+2GqygJg$btxn~5nmGnW|~|HsMPg4vYQl84!h-@=5) zl#hqql8Zg%0$UoLi+!fUk(HW1gxootklQ#<9L+p08&PYNr1md zsEC3v8DXp05D;V#a#G@&-Yci;0rq-_!RL=oXUGGb8XbEE9uzA-$W1Yq+;_#SiaIC- zmZFtsq6a)rW3cvh-8qTbj~phTZXiQy)?bsOZ#AKm-r{BoOitI=0v3kDTokOEXOJ7}d3i(f+ z3r)L`Y|O2!{3D~Fpx{V+FEB_kVdMsi3NDVg>WVy|1%X?Y7n;_LTtUyPuCD3Ed%+x? z))OcvJN@AC*Rj+NFbKtmTD?s8G zk#X;6aZAnetda4xz-0YfcjN7vioLnPu-VCL`6k=L%l%T@wV=@T%e8;4mvFq;ZaXT; zs^Ewd?ERJY@Mi|N3{8E#wtGO3^*U#B??KH8?)V!Q83nJqYNo0E1A1gao~5h1= z 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 z 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 A_W%F@ diff --git a/_versions/main/guides/images/webauthn-4.png b/_versions/main/guides/images/webauthn-4.png index 2da3b1d5a176e3e23025f5f7e3a8df5b80314ce3..934a175c7bdcd21aa38049d000a6dc4b51df7964 100644 GIT binary patch delta 17912 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 delta 19878 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 diff --git a/_versions/main/guides/images/webauthn-custom-login.svg b/_versions/main/guides/images/webauthn-custom-login.svg new file mode 100644 index 00000000000..e08ba0cd89e --- /dev/null +++ b/_versions/main/guides/images/webauthn-custom-login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_versions/main/guides/images/webauthn-custom-register.svg b/_versions/main/guides/images/webauthn-custom-register.svg new file mode 100644 index 00000000000..75b98727ac9 --- /dev/null +++ b/_versions/main/guides/images/webauthn-custom-register.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_versions/main/guides/images/webauthn-login.svg b/_versions/main/guides/images/webauthn-login.svg new file mode 100644 index 00000000000..0055a442c28 --- /dev/null +++ b/_versions/main/guides/images/webauthn-login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_versions/main/guides/images/webauthn-register.svg b/_versions/main/guides/images/webauthn-register.svg new file mode 100644 index 00000000000..5c60cdb486b --- /dev/null +++ b/_versions/main/guides/images/webauthn-register.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_versions/main/guides/rest-virtual-threads.adoc b/_versions/main/guides/rest-virtual-threads.adoc index 6af60d67b49..9de9a9bf4c7 100644 --- a/_versions/main/guides/rest-virtual-threads.adoc +++ b/_versions/main/guides/rest-virtual-threads.adoc @@ -53,7 +53,7 @@ and in particular, adds the following dependencies: .build.gradle ---- implementation("io.quarkus:quarkus-rest-jackson") -implementation("quarkus-rest-client-jackson") +implementation("io.quarkus:quarkus-rest-client-jackson") ---- [NOTE] diff --git a/_versions/main/guides/security-webauthn.adoc b/_versions/main/guides/security-webauthn.adoc index 996691c7a81..09ee4ce6b24 100644 --- a/_versions/main/guides/security-webauthn.adoc +++ b/_versions/main/guides/security-webauthn.adoc @@ -10,6 +10,8 @@ include::_attributes.adoc[] :categories: security :topics: security,webauthn,authorization :extensions: io.quarkus:quarkus-security-webauthn +:webauthn-api: https://javadoc.io/doc/io.quarkus/quarkus-security-webauthn/{quarkus-version} +:webauthn-test-api: https://javadoc.io/doc/io.quarkus/quarkus-test-security-webauthn/{quarkus-version} This guide demonstrates how your Quarkus application can use WebAuthn authentication instead of passwords. @@ -221,7 +223,7 @@ public class UserResource { === Storing our WebAuthn credentials -We can now describe how our WebAuthn credentials are stored in our database with three entities. Note that we've +We can now describe how our WebAuthn credentials are stored in our database with two entities. Note that we've simplified the model in order to only store one credential per user (who could actually have more than one WebAuthn credential and other data such as roles): @@ -229,139 +231,65 @@ and other data such as roles): ---- package org.acme.security.webauthn; -import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import io.quarkus.hibernate.orm.panache.PanacheEntityBase; +import io.quarkus.security.webauthn.WebAuthnCredentialRecord; +import io.quarkus.security.webauthn.WebAuthnCredentialRecord.RequiredPersistedData; import jakarta.persistence.Entity; -import jakarta.persistence.OneToMany; +import jakarta.persistence.Id; import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; - -import io.quarkus.hibernate.orm.panache.PanacheEntity; -import io.vertx.ext.auth.webauthn.Authenticator; -import io.vertx.ext.auth.webauthn.PublicKeyCredential; -@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"userName", "credID"})) @Entity -public class WebAuthnCredential extends PanacheEntity { - - /** - * The username linked to this authenticator - */ - public String userName; - - /** - * The type of key (must be "public-key") - */ - public String type = "public-key"; +public class WebAuthnCredential extends PanacheEntityBase { + + @Id + public String credentialId; - /** - * The non user identifiable id for the authenticator - */ - public String credID; - - /** - * The public key associated with this authenticator - */ - public String publicKey; - - /** - * The signature counter of the authenticator to prevent replay attacks - */ + public byte[] publicKey; + public long publicKeyAlgorithm; public long counter; - - public String aaguid; - - /** - * The Authenticator attestation certificates object, a JSON like: - *
{@code
-     *   {
-     *     "alg": "string",
-     *     "x5c": [
-     *       "base64"
-     *     ]
-     *   }
-     * }
- */ - /** - * The algorithm used for the public credential - */ - public PublicKeyCredential alg; - - /** - * The list of X509 certificates encoded as base64url. - */ - @OneToMany(mappedBy = "webAuthnCredential") - public List x5c = new ArrayList<>(); - - public String fmt; - - // owning side + public UUID aaguid; + + // this is the owning side @OneToOne public User user; public WebAuthnCredential() { } - - public WebAuthnCredential(Authenticator authenticator, User user) { - aaguid = authenticator.getAaguid(); - if(authenticator.getAttestationCertificates() != null) - alg = authenticator.getAttestationCertificates().getAlg(); - counter = authenticator.getCounter(); - credID = authenticator.getCredID(); - fmt = authenticator.getFmt(); - publicKey = authenticator.getPublicKey(); - type = authenticator.getType(); - userName = authenticator.getUserName(); - if(authenticator.getAttestationCertificates() != null - && authenticator.getAttestationCertificates().getX5c() != null) { - for (String x5c : authenticator.getAttestationCertificates().getX5c()) { - WebAuthnCertificate cert = new WebAuthnCertificate(); - cert.x5c = x5c; - cert.webAuthnCredential = this; - this.x5c.add(cert); - } - } + + public WebAuthnCredential(WebAuthnCredentialRecord credentialRecord, User user) { + RequiredPersistedData requiredPersistedData = + credentialRecord.getRequiredPersistedData(); + aaguid = requiredPersistedData.aaguid(); + counter = requiredPersistedData.counter(); + credentialId = requiredPersistedData.credentialId(); + publicKey = requiredPersistedData.publicKey(); + publicKeyAlgorithm = requiredPersistedData.publicKeyAlgorithm(); this.user = user; user.webAuthnCredential = this; } - public static List findByUserName(String userName) { - return list("userName", userName); + public WebAuthnCredentialRecord toWebAuthnCredentialRecord() { + return WebAuthnCredentialRecord + .fromRequiredPersistedData( + new RequiredPersistedData(user.userName, credentialId, + aaguid, publicKey, + publicKeyAlgorithm, counter)); } - public static List findByCredID(String credID) { - return list("credID", credID); + public static List findByUserName(String userName) { + return list("user.userName", userName); + } + + public static WebAuthnCredential findByCredentialId(String credentialId) { + return findById(credentialId); } } ---- -We also need a second entity for the credentials: - -[source,java] ----- -package org.acme.security.webauthn; - -import io.quarkus.hibernate.orm.panache.PanacheEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.ManyToOne; - - -@Entity -public class WebAuthnCertificate extends PanacheEntity { - - @ManyToOne - public WebAuthnCredential webAuthnCredential; - - /** - * The list of X509 certificates encoded as base64url. - */ - public String x5c; -} ----- - -And last but not least, our user entity: +And our user entity: [source,java] ---- @@ -392,98 +320,74 @@ public class User extends PanacheEntity { ==== A note about usernames and credential IDs -WebAuthn relies on a combination of usernames (unique per user) and credential IDs (unique per authenticator device). - -The reasons why there are two such identifiers, and why they are not unique keys for the credentials themselves are: - -- A single user can have more than one authenticator device, which means a single username can map to multiple credential IDs, - all of which identify the same user. -- An authenticator device may be shared by multiple users, because a single person may want multiple user accounts with different - usernames, all of which having the same authenticator device. So a single credential ID may be used by multiple different users. +Usernames are unique and to your users. Every created WebAuthn credential record has a unique ID. -The combination of username and credential ID should be a unicity constraint for your credentials table, though. +You can allow (if you want, but you don't have to) your users to have more than one authenticator device, +which means a single username can map to multiple credential IDs, all of which identify the same user. === Exposing your entities to Quarkus WebAuthn -You need to define a bean implementing the `WebAuthnUserProvider` in order to allow the Quarkus WebAuthn +You need to define a bean implementing the link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`] in order to allow the Quarkus WebAuthn extension to load and store credentials. This is where you tell Quarkus how to turn your data model into the WebAuthn security model: [source,java] ---- -package org.acme.security.webauthn; - import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; - -import io.smallrye.common.annotation.Blocking; -import jakarta.enterprise.context.ApplicationScoped; +import io.quarkus.security.webauthn.WebAuthnCredentialRecord; import io.quarkus.security.webauthn.WebAuthnUserProvider; +import io.smallrye.common.annotation.Blocking; import io.smallrye.mutiny.Uni; -import io.vertx.ext.auth.webauthn.AttestationCertificates; -import io.vertx.ext.auth.webauthn.Authenticator; +import jakarta.enterprise.context.ApplicationScoped; import jakarta.transaction.Transactional; -import static org.acme.security.webauthn.WebAuthnCredential.findByCredID; -import static org.acme.security.webauthn.WebAuthnCredential.findByUserName; - @Blocking @ApplicationScoped public class MyWebAuthnSetup implements WebAuthnUserProvider { @Transactional @Override - public Uni> findWebAuthnCredentialsByUserName(String userName) { - return Uni.createFrom().item(toAuthenticators(findByUserName(userName))); + public Uni> findByUserName(String userId) { + return Uni.createFrom().item( + WebAuthnCredential.findByUserName(userId) + .stream() + .map(WebAuthnCredential::toWebAuthnCredentialRecord) + .toList()); } @Transactional @Override - public Uni> findWebAuthnCredentialsByCredID(String credID) { - return Uni.createFrom().item(toAuthenticators(findByCredID(credID))); + public Uni findByCredentialId(String credId) { + WebAuthnCredential creds = WebAuthnCredential.findByCredentialId(credId); + if(creds == null) + return Uni.createFrom() + .failure(new RuntimeException("No such credential ID")); + return Uni.createFrom().item(creds.toWebAuthnCredentialRecord()); } @Transactional @Override - public Uni updateOrStoreWebAuthnCredentials(Authenticator authenticator) { - // leave the scooby user to the manual endpoint, because if we do it here it will be created/updated twice - if(!authenticator.getUserName().equals("scooby")) { - User user = User.findByUserName(authenticator.getUserName()); - if(user == null) { - // new user - User newUser = new User(); - newUser.userName = authenticator.getUserName(); - WebAuthnCredential credential = new WebAuthnCredential(authenticator, newUser); - credential.persist(); - newUser.persist(); - } else { - // existing user - user.webAuthnCredential.counter = authenticator.getCounter(); - } - } - return Uni.createFrom().nullItem(); + public Uni store(WebAuthnCredentialRecord credentialRecord) { + User newUser = new User(); + // We can only store one credential per userName thanks to the unicity constraint + // which will cause this transaction to fail and throw if the userName already exists + newUser.userName = credentialRecord.getUserName(); + WebAuthnCredential credential = new WebAuthnCredential(credentialRecord, newUser); + credential.persist(); + newUser.persist(); + return Uni.createFrom().voidItem(); } - private static List toAuthenticators(List dbs) { - return dbs.stream().map(MyWebAuthnSetup::toAuthenticator).collect(Collectors.toList()); - } - - private static Authenticator toAuthenticator(WebAuthnCredential credential) { - Authenticator ret = new Authenticator(); - ret.setAaguid(credential.aaguid); - AttestationCertificates attestationCertificates = new AttestationCertificates(); - attestationCertificates.setAlg(credential.alg); - ret.setAttestationCertificates(attestationCertificates); - ret.setCounter(credential.counter); - ret.setCredID(credential.credID); - ret.setFmt(credential.fmt); - ret.setPublicKey(credential.publicKey); - ret.setType(credential.type); - ret.setUserName(credential.userName); - return ret; + @Transactional + @Override + public Uni update(String credentialId, long counter) { + WebAuthnCredential credential = + WebAuthnCredential.findByCredentialId(credentialId); + credential.counter = counter; + return Uni.createFrom().voidItem(); } @Override @@ -496,6 +400,25 @@ public class MyWebAuthnSetup implements WebAuthnUserProvider { } ---- +Warning: When implementing your own `WebAuthnUserProvider.store` method, make sure that you never allow creating +new credentials for a `userName` that already exists. Otherwise you risk allowing third-parties to impersonate existing +users by letting them add their own credentials to existing accounts. If you want to allow existing users to register +more than one WebAuthn credential, you must make sure in `WebAuthnUserProvider.store` that the user is currently logged +in under the same `userName` to which you want to add new credentials. In every other case, make sure to return a failed +`Uni` from this method. In this particular example, this is checked using a unicity constraint on the user name, which +will cause the transaction to fail if the user already exists. + +== Configuration + +Because we want to delegate login and registration to the default Quarkus WebAuthn endpoints, we need to enable them +in configuration (`src/main/resources/application.properties`): + +[source,properties] +---- +quarkus.webauthn.enable-login-endpoint=true +quarkus.webauthn.enable-registration-endpoint=true +---- + == Writing the HTML application We now need to write a web page with links to all our APIs, as well as a way to register a new user, login, and logout, @@ -563,7 +486,6 @@ in `src/main/resources/META-INF/resources/index.html`:

Login

-

@@ -578,11 +500,7 @@ in `src/main/resources/META-INF/resources/index.html`: + +---- + +Or, if you need to customise the endpoints: + [source,javascript] ---- ---- +=== CSRF considerations + +If you use the endpoints provided by Quarkus, they will not be protected by xdoc:security-csrf-prevention.adoc[CSRF], but +if you define your own endpoints and use this JavaScript library to access them you will need to configure CSRF via headers: + +[source,javascript] +---- + + +---- + === Invoke registration -The `webAuthn.register` method invokes the registration challenge endpoint, then calls the authenticator and invokes the callback endpoint +The `webAuthn.register` method invokes the registration challenge endpoint, then calls the authenticator and invokes the registration endpoint for that registration, and returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise object]: [source,javascript] @@ -847,12 +866,12 @@ webAuthn.register({ name: userName, displayName: firstName + " " + lastName }) === Invoke login -The `webAuthn.login` method invokes the login challenge endpoint, then calls the authenticator and invokes the callback endpoint +The `webAuthn.login` method invokes the login challenge endpoint, then calls the authenticator and invokes the login endpoint for that login, and returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise object]: [source,javascript] ---- -webAuthn.login({ name: userName }) +webAuthn.login({ name: userName }) <1> .then(body => { // do something now that the user is logged in }) @@ -861,16 +880,18 @@ webAuthn.login({ name: userName }) }); ---- +<1> The name is optional, in the case of https://www.w3.org/TR/webauthn-3/#discoverable-credential[Discoverable Credentials] (with PassKeys) + === Only invoke the registration challenge and authenticator -The `webAuthn.registerOnly` method invokes the registration challenge endpoint, then calls the authenticator and returns +The `webAuthn.registerClientSteps` method invokes the registration challenge endpoint, then calls the authenticator and returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise object] containing a -JSON object suitable for being sent to the callback endpoint. You can use that JSON object in order to store the credentials +JSON object suitable for being sent to the registration endpoint. You can use that JSON object in order to store the credentials in hidden form `input` elements, for example, and send it as part of a regular HTML form: [source,javascript] ---- -webAuthn.registerOnly({ name: userName, displayName: firstName + " " + lastName }) +webAuthn.registerClientSteps({ name: userName, displayName: firstName + " " + lastName }) .then(body => { // store the registration JSON in form elements document.getElementById('webAuthnId').value = body.id; @@ -886,14 +907,14 @@ webAuthn.registerOnly({ name: userName, displayName: firstName + " " + lastName === Only invoke the login challenge and authenticator -The `webAuthn.loginOnly` method invokes the login challenge endpoint, then calls the authenticator and returns +The `webAuthn.loginClientSteps` method invokes the login challenge endpoint, then calls the authenticator and returns a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise[Promise object] containing a -JSON object suitable for being sent to the callback endpoint. You can use that JSON object in order to store the credentials +JSON object suitable for being sent to the login endpoint. You can use that JSON object in order to store the credentials in hidden form `input` elements, for example, and send it as part of a regular HTML form: [source,javascript] ---- -webAuthn.loginOnly({ name: userName }) +webAuthn.loginClientSteps({ name: userName }) <1> .then(body => { // store the login JSON in form elements document.getElementById('webAuthnId').value = body.id; @@ -909,25 +930,95 @@ webAuthn.loginOnly({ name: userName }) }); ---- +<1> The name is optional, in the case of https://www.w3.org/TR/webauthn-3/#discoverable-credential[Discoverable Credentials] (with PassKeys) + == Handling login and registration endpoints yourself Sometimes, you will want to ask for more data than just a username in order to register a user, -or you want to deal with login and registration with custom validation, and so the WebAuthn callback -endpoint is not enough. +or you want to deal with login and registration with custom validation, and so the default WebAuthn login +and registration endpoints are not enough. -In this case, you can use the `WebAuthn.loginOnly` and `WebAuthn.registerOnly` methods from the JavaScript +In this case, you can use the `WebAuthn.loginClientSteps` and `WebAuthn.registerClientSteps` methods from the JavaScript library, store the authenticator data in hidden form elements, and send them as part of your form payload to the server to your custom login or registration endpoints. -If you are storing them in form input elements, you can then use the `WebAuthnLoginResponse` and -`WebAuthnRegistrationResponse` classes, mark them as `@BeanParam` and then use the `WebAuthnSecurity.login` -and `WebAuthnSecurity.register` methods to replace the `/q/webauthn/callback` endpoint. This even -allows you to create two separate endpoints for handling login and registration at different endpoints. +If you are storing them in form input elements, you can then use the link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnLoginResponse.html[`WebAuthnLoginResponse`] and +link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnRegistrationResponse.html[`WebAuthnRegistrationResponse`] classes, +mark them as `@BeanParam` and then use the +link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html#login(io.quarkus.security.webauthn.WebAuthnLoginResponse,io.vertx.ext.web.RoutingContext)[`WebAuthnSecurity.login`] +and link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html#register(io.quarkus.security.webauthn.WebAuthnRegisterResponse,io.vertx.ext.web.RoutingContext)[`WebAuthnSecurity.register`] +methods to replace the `/q/webauthn/login` and `/q/webauthn/register` endpoints. -In most cases you can keep using the `/q/webauthn/login` and `/q/webauthn/register` challenge-initiating +In most cases you can keep using the `/q/webauthn/login-options-challenge` and `/q/webauthn/register-options-challenge` challenge-initiating endpoints, because this is not where custom logic is required. -For example, here's how you can handle a custom login and register action: +In this case, the registration flow is a little different because you will write your own registration endpoint +which will handle storing of the credentials and setting up the session cookie: + +image::webauthn-custom-register.svg[role="thumb"] + +Similarly, the login flow is a little different because you will write your own login endpoint +which will handle updating the credentials and setting up the session cookie: + +image::webauthn-custom-login.svg[role="thumb"] + +If you handle user and credential creation and logins yourself in your endpoints, you only need +to provide a read-only view of your entities in your link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`], so you can skip +the `store` and `update` methods: + +[source,java] +---- +package org.acme.security.webauthn; + +import java.util.List; + +import io.quarkus.security.webauthn.WebAuthnCredentialRecord; +import io.quarkus.security.webauthn.WebAuthnUserProvider; +import io.smallrye.common.annotation.Blocking; +import io.smallrye.mutiny.Uni; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; +import model.WebAuthnCredential; + +@Blocking +@ApplicationScoped +public class MyWebAuthnSetup implements WebAuthnUserProvider { + + @Transactional + @Override + public Uni> findByUserName(String userName) { + return Uni.createFrom().item( + WebAuthnCredential.findByUserName(userName) + .stream() + .map(WebAuthnCredential::toWebAuthnCredentialRecord) + .toList()); + } + + @Transactional + @Override + public Uni findByCredentialId(String credentialId) { + WebAuthnCredential creds = WebAuthnCredential.findByCredentialId(credentialId); + if(creds == null) + return Uni.createFrom() + .failure(new RuntimeException("No such credential ID")); + return Uni.createFrom().item(creds.toWebAuthnCredentialRecord()); + } + + @Override + public Set getRoles(String userId) { + if(userId.equals("admin")) { + return Set.of("user", "admin"); + } + return Collections.singleton("user"); + } +} +---- + +NOTE: When setting up your own login and registration endpoints, you don't need to enable the default endpoints, so you can +remove the `quarkus.webauthn.enable-login-endpoint` and `quarkus.webauthn.enable-registration-endpoint` configuration. + +Thankfully, you can use the link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html[`WebAuthnSecurity`] bean to handle the WebAuthn-specific part of +your registration and login endpoints, and focus on your own logic: [source,java] ---- @@ -943,10 +1034,10 @@ import jakarta.ws.rs.core.Response.Status; import org.jboss.resteasy.reactive.RestForm; +import io.quarkus.security.webauthn.WebAuthnCredentialRecord; import io.quarkus.security.webauthn.WebAuthnLoginResponse; import io.quarkus.security.webauthn.WebAuthnRegisterResponse; import io.quarkus.security.webauthn.WebAuthnSecurity; -import io.vertx.ext.auth.webauthn.Authenticator; import io.vertx.ext.web.RoutingContext; @Path("") @@ -955,29 +1046,28 @@ public class LoginResource { @Inject WebAuthnSecurity webAuthnSecurity; - // Provide an alternative implementation of the /q/webauthn/callback endpoint, only for login + // Provide an alternative implementation of the /q/webauthn/login endpoint @Path("/login") @POST @Transactional - public Response login(@RestForm String userName, - @BeanParam WebAuthnLoginResponse webAuthnResponse, + public Response login(@BeanParam WebAuthnLoginResponse webAuthnResponse, RoutingContext ctx) { // Input validation - if(userName == null || userName.isEmpty() || !webAuthnResponse.isSet() || !webAuthnResponse.isValid()) { + if(!webAuthnResponse.isSet() || !webAuthnResponse.isValid()) { return Response.status(Status.BAD_REQUEST).build(); } - User user = User.findByUserName(userName); - if(user == null) { - // Invalid user - return Response.status(Status.BAD_REQUEST).build(); - } try { - Authenticator authenticator = this.webAuthnSecurity.login(webAuthnResponse, ctx).await().indefinitely(); + WebAuthnCredentialRecord credentialRecord = this.webAuthnSecurity.login(webAuthnResponse, ctx).await().indefinitely(); + User user = User.findByUserName(credentialRecord.getUserName()); + if(user == null) { + // Invalid user + return Response.status(Status.BAD_REQUEST).build(); + } // bump the auth counter - user.webAuthnCredential.counter = authenticator.getCounter(); + user.webAuthnCredential.counter = credentialRecord.getCounter(); // make a login cookie - this.webAuthnSecurity.rememberUser(authenticator.getUserName(), ctx); + this.webAuthnSecurity.rememberUser(credentialRecord.getUserName(), ctx); return Response.ok().build(); } catch (Exception exception) { // handle login failure - make a proper error response @@ -985,7 +1075,7 @@ public class LoginResource { } } - // Provide an alternative implementation of the /q/webauthn/callback endpoint, only for registration + // Provide an alternative implementation of the /q/webauthn/register endpoint @Path("/register") @POST @Transactional @@ -993,7 +1083,8 @@ public class LoginResource { @BeanParam WebAuthnRegisterResponse webAuthnResponse, RoutingContext ctx) { // Input validation - if(userName == null || userName.isEmpty() || !webAuthnResponse.isSet() || !webAuthnResponse.isValid()) { + if(userName == null || userName.isEmpty() + || !webAuthnResponse.isSet() || !webAuthnResponse.isValid()) { return Response.status(Status.BAD_REQUEST).build(); } @@ -1004,10 +1095,12 @@ public class LoginResource { } try { // store the user - Authenticator authenticator = this.webAuthnSecurity.register(webAuthnResponse, ctx).await().indefinitely(); + WebAuthnCredentialRecord credentialRecord = + webAuthnSecurity.register(userName, webAuthnResponse, ctx).await().indefinitely(); User newUser = new User(); - newUser.userName = authenticator.getUserName(); - WebAuthnCredential credential = new WebAuthnCredential(authenticator, newUser); + newUser.userName = credentialRecord.getUserName(); + WebAuthnCredential credential = + new WebAuthnCredential(credentialRecord, newUser); credential.persist(); newUser.persist(); // make a login cookie @@ -1022,28 +1115,32 @@ public class LoginResource { } ---- -NOTE: The `WebAuthnSecurity` methods do not set or read the user cookie, so you will have to take care +NOTE: The link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html[`WebAuthnSecurity`] +methods do not set or read the <>, so you will have to take care of it yourself, but it allows you to use other means of storing the user, such as JWT. You can use the -`rememberUser(String userName, RoutingContext ctx)` and `logout(RoutingContext ctx)` methods on the same -`WebAuthnSecurity` class if you want to manually set up login cookies. +link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html#rememberUser(java.lang.String,io.vertx.ext.web.RoutingContext)[`WebAuthnSecurity.rememberUser`] + and link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html#logout(io.vertx.ext.web.RoutingContext)[`WebAuthnSecurity.logout`] + methods on the same link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html[`WebAuthnSecurity`] class if you want to manually set up login cookies. == Blocking version -If you're using a blocking data access to the database, you can safely block on the `WebAuthnSecurity` methods, +If you're using a blocking data access to the database, you can safely block on the +link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html[`WebAuthnSecurity`] methods, with `.await().indefinitely()`, because nothing is async in the `register` and `login` methods, besides the -data access with your `WebAuthnUserProvider`. +data access with your link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`]. -You will have to add the `@Blocking` annotation on your `WebAuthnUserProvider` class in order to tell the +You will have to add the `@Blocking` annotation on your link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`] class in order for the Quarkus WebAuthn endpoints to defer those calls to the worker pool. == Virtual-Threads version -If you're using a blocking data access to the database, you can safely block on the `WebAuthnSecurity` methods, +If you're using a blocking data access to the database, you can safely block on the +link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnSecurity.html[`WebAuthnSecurity`] methods, with `.await().indefinitely()`, because nothing is async in the `register` and `login` methods, besides the -data access with your `WebAuthnUserProvider`. +data access with your link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`]. -You will have to add the `@RunOnVirtualThread` annotation on your `WebAuthnUserProvider` class in order to tell the -Quarkus WebAuthn endpoints to defer those calls to virtual threads. +You will have to add the `@RunOnVirtualThread` annotation on your link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`] class in order to tell the +Quarkus WebAuthn endpoints to defer those calls to the worker pool. == Testing WebAuthn @@ -1066,8 +1163,10 @@ Testing WebAuthn can be complicated because normally you need a hardware token, testImplementation("io.quarkus:quarkus-test-security-webauthn") ---- -With this, you can use `WebAuthnHardware` to emulate an authenticator token, as well as the -`WebAuthnEndpointHelper` helper methods in order to invoke the WebAuthn endpoints, or even fill your form +With this, you can use link:{webauthn-test-api}/io/quarkus/test/security/webauthn/WebAuthnHardware.html[`WebAuthnHardware`] +to emulate an authenticator token, as well as the +link:{webauthn-test-api}/io/quarkus/test/security/webauthn/WebAuthnEndpointHelper.html[`WebAuthnEndpointHelper`] +helper methods in order to invoke the WebAuthn endpoints, or even fill your form data for custom endpoints: [source,java] @@ -1076,25 +1175,24 @@ package org.acme.security.webauthn.test; import static io.restassured.RestAssured.given; +import java.net.URL; import java.util.function.Consumer; -import java.util.function.Supplier; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; -import io.quarkus.security.webauthn.WebAuthnController; +import io.quarkus.test.common.http.TestHTTPResource; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.security.webauthn.WebAuthnEndpointHelper; import io.quarkus.test.security.webauthn.WebAuthnHardware; import io.restassured.RestAssured; import io.restassured.filter.Filter; -import io.restassured.http.ContentType; import io.restassured.specification.RequestSpecification; import io.vertx.core.json.JsonObject; @QuarkusTest public class WebAuthnResourceTest { - + enum User { USER, ADMIN; } @@ -1102,6 +1200,9 @@ public class WebAuthnResourceTest { DEFAULT, MANUAL; } + @TestHTTPResource + URL url; + @Test public void testWebAuthnUser() { testWebAuthn("FroMage", User.USER, Endpoint.DEFAULT); @@ -1112,42 +1213,41 @@ public class WebAuthnResourceTest { public void testWebAuthnAdmin() { testWebAuthn("admin", User.ADMIN, Endpoint.DEFAULT); } - + private void testWebAuthn(String userName, User user, Endpoint endpoint) { Filter cookieFilter = new RenardeCookieFilter(); - WebAuthnHardware token = new WebAuthnHardware(); + WebAuthnHardware token = new WebAuthnHardware(url); verifyLoggedOut(cookieFilter); // two-step registration - String challenge = WebAuthnEndpointHelper.invokeRegistration(userName, cookieFilter); + String challenge = WebAuthnEndpointHelper.obtainRegistrationChallenge(userName, cookieFilter); JsonObject registrationJson = token.makeRegistrationJson(challenge); if(endpoint == Endpoint.DEFAULT) - WebAuthnEndpointHelper.invokeCallback(registrationJson, cookieFilter); + WebAuthnEndpointHelper.invokeRegistration(userName, registrationJson, cookieFilter); else { invokeCustomEndpoint("/register", cookieFilter, request -> { WebAuthnEndpointHelper.addWebAuthnRegistrationFormParameters(request, registrationJson); request.formParam("userName", userName); }); } - + // verify that we can access logged-in endpoints verifyLoggedIn(cookieFilter, userName, user); - + // logout WebAuthnEndpointHelper.invokeLogout(cookieFilter); - + verifyLoggedOut(cookieFilter); - + // two-step login - challenge = WebAuthnEndpointHelper.invokeLogin(userName, cookieFilter); + challenge = WebAuthnEndpointHelper.obtainLoginChallenge(null, cookieFilter); JsonObject loginJson = token.makeLoginJson(challenge); if(endpoint == Endpoint.DEFAULT) - WebAuthnEndpointHelper.invokeCallback(loginJson, cookieFilter); + WebAuthnEndpointHelper.invokeLogin(loginJson, cookieFilter); else { invokeCustomEndpoint("/login", cookieFilter, request -> { WebAuthnEndpointHelper.addWebAuthnLoginFormParameters(request, loginJson); - request.formParam("userName", userName); }); } @@ -1156,7 +1256,7 @@ public class WebAuthnResourceTest { // logout WebAuthnEndpointHelper.invokeLogout(cookieFilter); - + verifyLoggedOut(cookieFilter); } @@ -1173,7 +1273,6 @@ public class WebAuthnResourceTest { .statusCode(200) .log().ifValidationFails() .cookie(WebAuthnEndpointHelper.getChallengeCookie(), Matchers.is("")) - .cookie(WebAuthnEndpointHelper.getChallengeUsernameCookie(), Matchers.is("")) .cookie(WebAuthnEndpointHelper.getMainCookie(), Matchers.notNullValue()); } @@ -1200,7 +1299,7 @@ public class WebAuthnResourceTest { .then() .statusCode(200) .body(Matchers.is(userName)); - + // admin API? if(user == User.ADMIN) { RestAssured.given().filter(cookieFilter) @@ -1243,7 +1342,7 @@ public class WebAuthnResourceTest { .then() .statusCode(302) .header("Location", Matchers.is("http://localhost:8081/")); - + // admin API not accessible RestAssured.given() .filter(cookieFilter) @@ -1258,32 +1357,45 @@ public class WebAuthnResourceTest { ---- For this test, since we're testing both the provided callback endpoint, which updates users -in its `WebAuthnUserProvider` and the manual `LoginResource` endpoint, which deals with users -manually, we need to override the `WebAuthnUserProvider` with one that doesn't update the +in its link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`] and the manual `LoginResource` endpoint, which deals with users +manually, we need to override the link:{webauthn-api}/io/quarkus/security/webauthn/WebAuthnUserProvider.html[`WebAuthnUserProvider`] with one that doesn't update the `scooby` user: [source,java] ---- package org.acme.security.webauthn.test; -import jakarta.enterprise.context.ApplicationScoped; - import org.acme.security.webauthn.MyWebAuthnSetup; +import org.acme.security.webauthn.WebAuthnCredential; +import io.quarkus.security.webauthn.WebAuthnCredentialRecord; import io.quarkus.test.Mock; import io.smallrye.mutiny.Uni; -import io.vertx.ext.auth.webauthn.Authenticator; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; @Mock @ApplicationScoped public class TestUserProvider extends MyWebAuthnSetup { + @Transactional + @Override + public Uni store(WebAuthnCredentialRecord credentialRecord) { + // this user is handled in the LoginResource endpoint manually + if (credentialRecord.getUserName().equals("scooby")) { + return Uni.createFrom().voidItem(); + } + return super.store(credentialRecord); + } + + @Transactional @Override - public Uni updateOrStoreWebAuthnCredentials(Authenticator authenticator) { - // delegate the scooby user to the manual endpoint, because if we do it here it will be - // created/updated twice - if(authenticator.getUserName().equals("scooby")) - return Uni.createFrom().nullItem(); - return super.updateOrStoreWebAuthnCredentials(authenticator); + public Uni update(String credentialId, long counter) { + WebAuthnCredential credential = WebAuthnCredential.findByCredentialId(credentialId); + // this user is handled in the LoginResource endpoint manually + if (credential.user.userName.equals("scooby")) { + return Uni.createFrom().voidItem(); + } + return super.update(credentialId, counter); } } ----