-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reimplement security-webauthn on top of webauthn4j #44105
Conversation
Huh, I had completely forgotten I added |
And quickstarts are at quarkusio/quarkus-quickstarts#1470 |
WebAuthnHelper part is #44106 |
🙈 The PR is closed and the preview is expired. |
This comment has been minimized.
This comment has been minimized.
Sorry I'm noob in webauthn - does this break users or allow them to coexist ? And what kind of users are affected - Quarkus app devs or/and ext dev? |
The compatibility breakage is for users, but the module is in preview so we can break. |
Quickstarts break is handled by the PR. The native one I need to look at. |
Native should pass now. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Will check tomorrow evening. |
Hi Steph, @FroMage, thanks for this major enhancement/refactoring, I have to do some homework to do a proper review, need to refresh some WebAuthn concepts and check webauthn4j docs, may take a bit of time, but I'm on it, cheers |
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnSecurity.java
Outdated
Show resolved
Hide resolved
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnSecurity.java
Outdated
Show resolved
Hide resolved
&& config.attestation().get() == WebAuthnRunTimeConfig.Attestation.ENTERPRISE) { | ||
TrustAnchorAsyncRepository something; | ||
// FIXME: make config name configurable? | ||
Optional<TlsConfiguration> webauthnTlsConfiguration = certificates.get("webauthn"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebAuthn attestation certificate is not related to TLS.
Is it appropriate to use TlsConfigurationRegistry
for webauthn attestation certificate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's definitely not related to TLS, but for some reason the Quarkus certificate registry is called the TLS registry https://quarkus.io/guides/tls-registry-reference
This is just how every certificate list (and trust stores, private, public keys) are configured in Quarkus.
I do agree that the name implies a single purpose that is limiting, @cescoffier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha ha, @sberyozkin stopped me from using it from anything that is not TLS when I integrated this registry to OIDC. I agree, it would be nice to have Quarkus certificate registry, but there are things that doesn't make sense when you use it this way. Like handshakeTimeout
, alpn
and other stuff. I suppose it is fine for your use case because I think users does not configure this, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, @cescoffier himself told me to use this, to centralise everything 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@FroMage TLS registry entries have properties related to TLS like handshake timeout, host verification options, reload related one, etc. If the attestation is not happening on the TLS path, it can be confusing for Quarkus WebAuthn users having to refer to TLS registry...
TLS registry is a great concept, but perhaps it can be enhanced over time to extend say TrustStoreRegistry
instead of having to refer to it on the non-TLS paths
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnSecurity.java
Outdated
Show resolved
Hide resolved
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java
Outdated
Show resolved
Hide resolved
...urity-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRunTimeConfig.java
Outdated
Show resolved
Hide resolved
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRecorder.java
Show resolved
Hide resolved
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnSecurity.java
Outdated
Show resolved
Hide resolved
...security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnController.java
Outdated
Show resolved
Hide resolved
Sorry, it has been hectic week I must look later. But since @ynojima and @sberyozkin are going to have a look, I think it's not an issue. Great PR. |
...s/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnSecurity.java
Outdated
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Rebased on |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@FroMage Can you please look at the Quickstart compilation issue and we can merge ? Indeed, it needs some settle-in time and for users to start experimenting, hard to make such a big refactoring perfect from the very start. I'd also consider changing https://github.com/quarkusio/quarkus/blob/main/extensions/security-webauthn/runtime/src/main/resources/META-INF/quarkus-extension.yaml status to |
The quickstart PR is already waiting. It fails because it can't compile without this PR being merged. It's a chicken-egg problem.
Sure, that makes sense. |
…security/webauthn/WebAuthnUserProvider.java Co-authored-by: Sergey Beryozkin <[email protected]>
…security/webauthn/WebAuthnUserProvider.java Co-authored-by: Sergey Beryozkin <[email protected]>
Status for workflow
|
Status for workflow
|
Status | Name | Step | Failures | Logs | Raw logs | Build scan |
---|---|---|---|---|---|---|
✖ | Quickstarts Compilation - JDK 17 | Compile Quickstarts |
Failures | Logs | Raw logs | 🚧 |
✖ | Native Tests - Virtual Thread - Messaging | Build |
Logs | Raw logs | 🔍 |
You can consult the Develocity build scans.
Failures
⚙️ Quickstarts Compilation - JDK 17 #
- Failing: security-webauthn-quickstart security-webauthn-reactive-quickstart
📦 security-webauthn-quickstart
✖ Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project security-webauthn-quickstart: Compilation failure
📦 security-webauthn-reactive-quickstart
✖ Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project security-webauthn-reactive-quickstart: Compilation failure
Flaky tests - Develocity
⚙️ Native Tests - Messaging1
📦 integration-tests/reactive-messaging-kafka
✖ io.quarkus.it.kafka.KafkaConnectorIT.testRequestReply
- History
iterable contents differ at index [2], expected: <reply-3> but was: <{"details":"Error id edb8cb3a-bc93-4331-ae9f-aa3fb9ba0561-1","stack":""}>
-org.opentest4j.AssertionFailedError
org.opentest4j.AssertionFailedError: iterable contents differ at index [2], expected: <reply-3> but was: <{"details":"Error id edb8cb3a-bc93-4331-ae9f-aa3fb9ba0561-1","stack":""}>
at io.quarkus.it.kafka.KafkaConnectorTest.testRequestReply(KafkaConnectorTest.java:112)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:788)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Thanks. |
I was going to ask for integrating something in the migration guide but it's already done! Thanks! |
This is following in the footsteps of the new vertx-auth-webauthn4j, which we're not using here because there was no point in converting our config to vertx config which converts to webauthn4j config.
I also took the opportunity to improve the docs and fix the API and endpoints to remove confusion.
As a result, this is not compatible with the previous API, here's the proposed migration guide, which I'll add in the migration notes as soon as we know where we merge this.
== Migration Guide
The
quarkus-security-webauthn
module has been reimplemented on top of WebAuthn4J. As a result, it is not binary or source compatible with the previous versions, and you must update the following code:Authenticator
typeAuthenticator
class (from Vert.x) is no longer used, and has been replaced functionally withWebAuthnCredentialRecord
. It holds similar data to the previous class, but as it is a subtype of a WebAuthn4J type, accessing its content is slightly different.WebAuthnCredentialRecord
now has agetRequiredPersistedData()
method which returns aRequiredPersistedData
record holding all the data you need to persist to your data source (database, or anything persistent), to make it easier.WebAuthnCredentialRecord.fromRequiredPersistedData(RequiredPersistedData)
allows you to turn your stored data into aWebAuthnCredentialRecord
for the opposite operation.Authenticator
format of data, you will need to update them to the new set of data. Open an issue if you need help for that.WebAuthnUserProvider
type that you had to implement has been restructured:findWebAuthnCredentialsByUserName()
was renamed tofindByUserName()
findWebAuthnCredentialsByCredID()
was renamed tofindByCredentialId()
updateOrStoreWebAuthnCredentials
was split into the two methods it represented:update(String credentialId, long counter)
andstore(WebAuthnCredentialRecord credentialRecord)
/q/webauthn/login
was renamed to/q/webauthn/login-options-challenge
/q/webauthn/register
was renamed to/q/webauthn/register-options-challenge
/q/webauthn/callback
was split into the two operations it represented:/q/webauthn/login
and/q/webauthn/register
. These endpoints are now disabled by default (for security reasons) and can be enabled using thequarkus.webauthn.enable-registration-endpoint
andquarkus.webauthn.enable-login-endpoint
configuration properties./q/webauthn/register
now requires ausername
query parameter./.well-known/webauthn
was added to return the list of allowed related originslogin
andlogin-options-challenge
is now optionalWebAuthnSecurity
WebAuthnSecurity
:getLoginOptionsChallenge()
andgetRegisterOptionsChallenge()
to make it easier to call and customise them.login()
andloginOptionsChallenge()
is now optionalregister()
method now takes an additionaluserName
parameter (due to the removal of the username cookie)quarkus.webauthn.require-resident-key
(boolean defaulting tofalse
) setting has been replaced by thequarkus.webauthn.resident-key
(enum defaulting toREQUIRED
)quarkus.webauthn.challenge-username-cookie-name
setting has been removed along with its related cookie.quarkus.webauthn.load-metadata
(boolean defaulting tofalse
) setting has been added to control loading of FIDO metadata.quarkus.webauthn.user-presence-required
(boolean defaulting totrue
) setting has been added to control the requirement of user presence.quarkus.webauthn.user-verification
setting has changed default fromDISCOURAGED
toREQUIRED
.quarkus.webauthn.timeout
default has increased from1 minute
to5 minutes
as specified in the WebAuthn standardquarkus.webauthn.pub-key-cred-params
setting has been renamed toquarkus.webauthn.public-key-credential-parameters
quarkus.webauthn.origin
setting has been renamed toquarkus.webauthn.origins
(plural) and now allows more than one origin (as required by spec)quarkus.webauthn.enable-registration-endpoint
boolean configuration (defaults tofalse
) enables the default registration endpoint.quarkus.webauthn.enable-login-endpoint
boolean configuration (defaults tofalse
) enables the default login endpoint.quarkus.security.webauthn.attestation
other thanNONE
(the default).quarkus-test-security-webauthn
test module:WebAuthnHardware
contructor now requires aURL
to represent the location of your endpoints, you can obtain in your test classes it using@TestHTTPResource URL url
WebAuthnEndpointHelper.invokeRegistration
method was renamed toobtainRegistrationChallenge
WebAuthnEndpointHelper.invokeLogin
method was renamed toobtainLoginChallenge
WebAuthnEndpointHelper.invokeCallback
method was split into the two operations it represented:WebAuthnEndpointHelper.invokeRegistration
andWebAuthnEndpointHelper.invokeLogin
WebAuthnEndpointHelper.invokeLogin
andWebAuthnEndpointHelper.obtainLoginChallenge
user name parameter is now optionalWebAuthnEndpointHelper.invokeRegistration
method now takes auserName
parameterregisterOnly
method has been renamed toregisterClientSteps
loginOnly
method has been renamed tologinClientSteps
login
andloginClientSteps
method'suser
parameter is now optionalregisterPath
has been renamed toregisterOptionsChallengePath
and has the default value/q/webauthn/register-options-challenge
loginPath
has been renamed tologinOptionsChallengePath
and has the default value/q/webauthn/login-options-challenge
callbackPath
has been split into its two componentsregisterPath
(default value/q/webauthn/register
) andloginPath
(default value/q/webauthn/login
csrf
option of typeJsonObject
with two keys:header
for the header name to use to add the CSRF token, andvalue
for the CSRF token value. This is mostly useful when usingquarkus-csrf
and using custom endpoints that are protected by CSRF (unlike the default endpoints).