-
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
WebAuthn extension #24316
WebAuthn extension #24316
Conversation
@FroMage I don't have write permissions on quarkus, so I'll make a fork from your repo and do PR's against your branch so you can cherry pick and push to quarkus. Is this OK? |
Sure, thanks :) |
@pmlopes One of the problems @FroMage is seeing is that
|
I don't think we have a test module for HTTP related stuff |
@FroMage @cescoffier I could create a specific constructor on Or I can update the current constructor to do a try catch and if it fails, fallback to a local instance of PRNG. But I'm not sure if this try catch affects the native builds? /**
* Get or create a secure non blocking random number generator using the provided vert.x context. This method will not
* throw an exception.
*
* @param context a Vert.x context.
* @return A secure non blocking random number generator, or {@code null} if context access fails.
*/
@GenIgnore
static VertxContextPRNG current(final Context context) {
try {
final String contextKey = "__vertx.VertxContextPRNG";
// attempt to load a PRNG from the current context
PRNG random = context.get(contextKey);
if (random == null) {
synchronized (context) {
// attempt to reload to avoid double creation when we were
// waiting for the lock
random = context.get(contextKey);
if (random == null) {
// there was no PRNG in the context, create one
random = new PRNG(context.owner());
// need to make the random final
final PRNG rand = random;
// save to the context
context.put(contextKey, rand);
}
}
}
return random;
} catch (RuntimeException e) {
// Access to the current context is probably blocked
return null;
}
} This would solve the problem for all places where we use |
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.
I've added some comments at the high-level config and JS script. Please have a look at the downstream PR that adds documentation.
...urity-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRunTimeConfig.java
Outdated
Show resolved
Hide resolved
...urity-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnRunTimeConfig.java
Show resolved
Hide resolved
//private JsonObject extensions; | ||
|
||
// FIXME | ||
//private Map<String, X509Certificate> rootCertificates; |
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.
You could enable this like in vert.x, you can use the "standard" base64 certificate encoder string:
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.
I'll leave this open until someone wants this. I don't feel good telling people to add base64 certificates in the config file, that's just bad UX.
If anything, I'd prefer the config to point at files:
quarkus.webauthn.root-certificates.something=something.pem
Or even a convention where these files get automatically configured src/main/resources/META-INF/webauthn/root/*.pem
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.
BTW, what's the point of the Map
? Why not just a list?
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.
The reason for the map was because older versions of vertx didn't supported all attestation modes and the root certificates are to be bound to a given attestation type. Internally vert.x uses a service loader to load the attestation implementations, so this was dynamic.
Perhaps we can improve the upstream code to not use a service loader as it now supports all attestations so we can define speicifc config properties, e.g.:
- android-safetynet
- android-key
- apple
And mds
(metadata service).
We could have a dual option too: either inline buffer (which you don't like) and a filesystem path.
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.
I'll leave this open until someone wants this.
Please note, that without this functionality you cannot claim that your implementation is FIDO CONFORMANT
as you cannot guarantee that Android and IPhone's are trustworthy if attestation is required.
Same for any kind of token that has been identified as faulty as MDS cannot be trusted.
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.
We can handle files downstream, that's no problem. But I still don't understand why this is a Map
, do you do anything special with the keys?
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.
yes, they need to match the attestation types:
- android-safetynet
- android-key
- apple
This way during the attestation we know which certificate to use.
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.
For reference, here's the service loader config:
And the names are coming from the interface:
//private Map<String, X509Certificate> rootCertificates; | ||
|
||
// FIXME | ||
//private List<X509CRL> rootCrls; |
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.
This one is like the previous. Without this, MDS doesn't work. MDS is important for PSD2.0 apps (banking/finance) where authenticators must be verified, for example, a bank should not trust a rooted android, as a bad actor could attempt to extract the private key from the hardware in case of security bugs.
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.
I'll leave this open until someone wants this. I don't feel good telling people to add base64 certificates in the config file, that's just bad UX.
If anything, I'd prefer the config to point at files:
quarkus.webauthn.root-crls=something.crl
Or even a convention where these files get automatically configured src/main/resources/META-INF/webauthn/root/*.crl
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.
Same as before, we can propose an upstream update that takes a list of files.
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.
Downstream can handle the files when we support this, no problem.
@@ -0,0 +1,241 @@ | |||
"use strict"; |
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.
Perhaps you should just include this from maven?
This will be updated once the new Level 3 spec is released as we hope that the API will handle JSON directly instead of this dance of encode/decode buffers.
Plus we need to support https://github.com/vert-x3/vertx-auth/issues/539 and you will start drifting from the original script and have double maintenance
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.
I have updated it with more methods, to be able to only do the first half and get the login/registration challenges without calling the callback.
@pmlopes You need to be absolutely sure PRNG is thread-safe, as with that you can have concurrent access. Anyway, yes, having another constructor that does use |
PRNG should be thread safe as it relies on The only extra thing PRNG is doing, is that it sets up a timer that reseeds the secure random, as described by the OWASP security best practices. |
@FroMage @cescoffier please review https://github.com/vert-x3/vertx-auth/pull/546 it should address the context issue and work not only for webauthn but for all vert.x code that uses it. |
...uthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnAuthenticationMechanism.java
Show resolved
Hide resolved
...uthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnAuthenticationMechanism.java
Show resolved
Hide resolved
...security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnController.java
Show resolved
Hide resolved
The Vert.x fix is at https://github.com/vert-x3/vertx-auth/pull/546 and will be in 4.2.6 |
… Which… has been released ! |
Awesome! That'd be really great! |
Hi @FroMage Sorry for a delay, IMHO it is quite close but I also think we should have 2 approvals here, @stuartwdouglas hi Stuart, can you also have a look please ? |
Ok, well, I have no problem merging this post CR1 as it's preview so we can take a little more time. But let's get it merged before the end of the week, please. |
@gsmet Thanks, it feels like we need another day or so |
...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/WebAuthnRecorder.java
Show resolved
Hide resolved
...ttp/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/PersistentLoginManager.java
Show resolved
Hide resolved
@FroMage Can you please start squashing the commits ? |
Look, if you insist, I'll sqash them all, and never mind for authors. I really don't care if you prefer that. |
@FroMage I don't mind either way, I've just asked Guillaume for his preference, my understanding it is OK to have more than one commit as long as they represent some specific additions. etc. It is nearly there but lets wait for Guillaume to decide on this one |
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 I think we should indeed position |
Yes, but the only difference between the two is that the credentials get passed via headers all the time, or via a form that gets you a login header (cookie, but that's the same thing as a bearer token) |
The commits are semantic, fine by me. |
Hum, this PR update to Vert.x 4.2.6, however, we do not have a constructor run for it yet, and the constructor reported issues with Vert.x main. Let's see how it goes, I would need to find slots on between my travels, as I believe we will have a bunch of issues. |
If you want to revert this change, I can delay the webauthn support. |
Given the fact that Vert.x 4.2.6 seems to be causing problems, I won't backport this to 2.8 for now. |
Apparently we did a 2.8.1.Final release with Vert.x 4.2.7, so perhaps we can backport this to 2.8 now @gsmet ? |
@FroMage FWIW, I preferred waiting for 2.9 as this feature needs proper exposure and micros don't really get that much exposure given people are not expecting new features. |
This is the infamous Quarkus WebAuthn extension, finally.
I'm making this a draft PR because since my rebase on the latest Quarkus, it fails due to a call to
Context.get
in the Vert.x WebAuthn extension, which hopefully @cescoffier and @pmlopes are going to help me with.Also, I'll need @pmlopes's help with the documentation for the
WebAuthnOptions
which I'm exposing as Quarkus config: they're undocumented so I can't document them.Once this is resolved I can turn this out of draft, but otherwise the tests are there, passing (well, minus the context issue), and the docs are written, and the quickstart PR is on its way.
Also, I have a question for @stuartwdouglas and @geoand: here I'm shipping a copy of
RenardeCookieFilter
which is a fix/fork of the RestAssuredCookieFilter
which has an invalid cookie expiry date parser that actually doesn't work. I'd like to add this class to an existing Quarkus test module so that everyone can use it, but I'm not sure which would be suitable, do you know?Fixes #9316