8000 Integrate current auth-username-password-form authenticator with passkeys isConditionalMediationAvailable by rmartinc · Pull Request #38781 · keycloak/keycloak · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Integrate current auth-username-password-form authenticator with passkeys isConditionalMediationAvailable #38781

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

Merged
merged 3 commits into from
Jun 5, 2025

Conversation

rmartinc
Copy link
Contributor
@rmartinc rmartinc commented Apr 9, 2025

Closes #29596

Draft PR for now that adds a new authenticator that extends the normal username password form authenticator with the isConditionalMediationAvailable login for passkeys. The main ideas are the following:

  • New method to return optional categories in authenticators.
  • The autocomplete attribute with the webauthn is added to the username input.
  • The user can use the passkey or common username/password variant.
  • If the passkey fails an error is presented and the webauthn option is removed (so if it fails, it goes back to only username/password). We can change this but for automated testing is complicated, selenium automatically uses the passkey generating a loop. I preferred to this way. We can also add the restart if needed.
  • The authenticator is new, so in the flow the normal username/password authenticator should be replaced by this new Passkeys Username Password Form.
  • Probably we need to continue providing variants for other authenticators (for example the single username authenticator, the one without password).
  • Tested manually using windows hello in latest versions of chrome and firefox.
  • Tests added using selenium.

Steps to test this:

  • Use the PR branch version, compile and start the server with --features passkeys.
  • Create a demo realm.
  • Go to authentication →Policies →Webauthn Passwordless Policy and configure Require discoverable credential to Yes and User verification requirement to required.
  • In authentication →Flows duplicate the browser flow.
  • Remove the Username password form step.
  • Add the new Passkeys username password form as required, move it to the same position it was the previous removed step (first inside the browser flows flow).
  • Bind the duplicated flow as the default one for browser flow.
  • Create a user and just login with it using username/password into the console.
  • Create a passwordless passkey in the Signing in page of the account console.
  • Logout and test the passkey to enter the account console again.

Little screencast from my windows VM (don't know why the cursor is lost, but you can see the idea). First normal password login, then the passkey login.

passkeys.mp4

*
* @author rmartinc
*/
public class PasskeysUsernamePasswordForm extends UsernamePasswordForm {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rmartinc Nice work! I really like this!

IMHO, in terms of this authenticator, I'd rather think about the passkeys/webauthn functionality as a FEATURE of the UsernamePasswordForm without the need to create a new authenticator.

I'd rather have some checkbox in the UsernamPasswordForm config like 'Or use passkeys'.

AFAIK, we already have quite a lot of authenticators, and it might become unintuitive for admins to know what to use. By limiting the creation of new authenticators and rather enhancing existing ones, we might get better UX. Or maybe even provide some sort of categories for authenticators to filter them out a little bit, based on their usage (but out of the scope).

On the other hand, I understand we might potentially introduce some breaking change for the authenticator impls, but if these changes are quite straightforward, I would not be so scared about that.

WDYT? Or do you have any other concerns?

It's just my humble opinion on this. Let me know what you think.
Great work, though 👍

< 8000 clipboard-copy aria-label="Copy link" for="discussion_r2035216701-permalink" role="menuitem" data-view-component="true" class="dropdown-item btn-link"> Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we have managed that idea too. I was adding a configuration option (disabled by default) to add passkeys. It can be done that way too with no problem. But @mposolda preferred this way. 😄 I don't know. I'm OK with both ideas.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rmartinc Ahh, ok, thanks for the info. It seems we have some collision of preferences xD

@rmartinc @mposolda Whatever works for you, guys, but I like more the config option in the current UsPass form.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that most probably we need to do the same for more authenticators. For example the auth-username-form (the one with only the username field) or the organization (the one used when organizations are enabled in the realm). So the decision will be repeated several times (we can have two variants for each authenticator or an option in each one).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rmartinc Yes, there are some similar authenticators created, indeed. Not sure about your plans, but having some general authenticator for these use cases with some additional features(orgs, passkeys, ...) seems more reasonable to me.

So, imagine a case when you'd like to provide the same functionality of passkey to the form authn organization. And what if there's another "feature" created that might be shared?

@mposolda What's your opinion on this? Of course, it might be out of scope of this PR, so we can discuss it somewhere else.

Copy link
Contributor
@mposolda mposolda May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mabartos My original preference was possibly checking if we can use something like FormActionSPI . So something, which will allow to build the individual authentication pages as "building blocks", which consists of multiple different pieces . That is also what I've originally commented on the linked issue. That may allow using other similar things (like for example adding "social buttons" to any other authentication page).

Currrently form-action SPI is used only on registration form and I am not sure how feasible it is to use it in the other parts. According to @rmartinc , it might be complicated.

Having config option on every authenticator may work too, but it means that config option needs to be on every "variant" of the authenticator if I understand correctly? Finally having subclasses for each variant (EG. PasskeysUsernamePasswordForm , PasskeysUsernameForm) is also similar option. Both of these have some disadvantage that it needs to change multiple authenticator classes and either include configuration option to them OR introduce subclasses for every form variant where we want to add passkeys.
The "Config option on each authenticator" is probably easier for the administrators as they can just enable passkey. However it might be harder for the maintenance of the code as you need to change sources of every authenticator, which we want to decorate, and add "passkeys" option to it.

@rmartinc
Copy link
Contributor Author
rmartinc commented May 6, 2025

Rebased to current main.

rmartinc added 2 commits May 26, 2025 14:39
…/password with isConditionalMediationAvailable

Closes keycloak#29596

Signed-off-by: rmartinc <rmartinc@redhat.com>
…or implementation

Use the webauthn passwordless policy to enable passkeys at realm level
Closes keycloak#29596

Signed-off-by: rmartinc <rmartinc@redhat.com>
@rmartinc
Copy link
Contributor Author
rmartinc commented May 26, 2025

OK, I have updated the PR with two changes:

  1. The current UsernamePassworfForm implementation is extended to integrate the passkeys/conditionalUI changes.
  2. The authenticator uses a new webauthn passwordless policy option to enable or disable the passkeys at realm level.

Id nobody says something different I will move this PR out of draft if the CI passes successfully. Simplified steps now:

  • Use the PR branch version, compile and start the server with --features passkeys.
  • Create a demo realm.
  • Go to authentication →Policies →Webauthn Passwordless Policy and configure Require discoverable credential to Yes, User verification requirement to required and Enable passkeys to On.
  • Create a user and just login with it using username/password into the console.
  • Create a passwordless passkey in the Signing in page of the account console.
  • Logout and test the passkey to enter the account console again.

@mposolda
Copy link
Contributor

@tnorimat Do you please have any feedback to this PR?

@rmartinc rmartinc changed the title Create new passkeys-username-password-form authenticator for username/password with isConditionalMediationAvailable Integrate current auth-username-password-form authenticator with passkeys isConditionalMediationAvailable May 28, 2025
@tnorimat
Copy link
Contributor

@mposolda Yes, I will review the PR in this week.

Copy link
Contributor
@tnorimat tnorimat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@tnorimat
Copy link
Contributor
tnorimat commented May 30, 2025

@rmartinc @mposolda I confirmed that Keycloak built from the PR works as you intented on my local environment. Thank you.
It might be better to send the PR for the documantation of the changes by the PR.

edewit
edewit previously approved these changes May 30, 2025
@Romain7495
Copy link
Contributor

Hi, thank you for this feature! I’ve tested the feature and I have two pieces of feedback:

  • Currently, it only works with UsernamePasswordForm and not with UsernameForm. Is this the intended behavior?

image

  • Physical passkeys are not being offered as an option.
    example:
    image
    image
    In the second screen, usb security key is missing

@rmartinc
Copy link
Contributor Author
rmartinc commented Jun 2, 2025

@Romain7495 See issue #40021 for the first question. This issue is only for the username and password form. The rest of forms will be added in different issues.

Regarding the second point it depends on the passkey. To be chosen the passkey should be discoverable and with user verification. But this is more a question for the browser than for us, we are using the JS method to ask for keys, the page relies on the browser once the method is called. Did you set the require discoverable to yes and the user verification to required in the policy? I suppose that with those two options the passkey will be created with the correct options or the creation will fail.

@Romain7495
Copy link
Contributor
Romain7495 commented Jun 2, 2025

@rmartinc thanks for your answser

Yes I had already configured the webauthn passwordless policy like this (still same after removing and re creating usb passkeys)
image

@rmartinc
Copy link
Contributor Author
rmartinc commented Jun 2, 2025

Thanks @Romain7495! I have been investigating the second issue and it seems the problem is intrinsic to the conditional UI interface. More or less it is explained in the following thread in reddit.

In that thread they recommend to always add the modal UI too (a direct button to start the modal UI). With this PR we are using only conditional UI. With the authenticator steps you can always add another step with passwordless (try another way button). But I'm thinking about adding the button to start the modal directly. @tnorimat @mposolda WDYT?

@tnorimat
Copy link
Contributor
tnorimat commented Jun 3, 2025

@rmartinc I read the reddit thread. I agree with your idea. It would be better if Conditional UI itself had supported the feature of picking up passkeys that satisfies some conditions (e.g., only device bound passkeys) we can set.

Closes keycloak#29596

Signed-off-by: rmartinc <rmartinc@redhat.com>
@rmartinc
Copy link
Contributor Author
rmartinc commented Jun 3, 2025

OK, I have updated the PR with mainly two changes:

  1. There is a link when passkeys are enabled that can be clicked to start modal UI.
  2. Now after trying the webauthn method the webauthn is not disabled. Previously I thought it was better but now with the button it remains after the user cancels for example. It makes sense now.

This is the login page now after adding the button:

Screenshot From 2025-06-03 11-35-36

@Romain7495 Can you please test that using the new button you can select the usb key?

@Romain7495
Copy link
Contributor
Romain7495 commented Jun 3, 2025

@rmartinc it works as expected 👍 Thanks

image
image

@Romain7495
Copy link
Contributor
Romain7495 commented Jun 3, 2025

If we have both icloud passkeys and device bound passkeys, icloud will prompt before the modal like in all other websites that I have tested 👌

image

after cancelling this icloud popup, we have :

image

@rmartinc
Copy link
Contributor Author
rmartinc commented Jun 3, 2025

Thanks @Romain7495! @tnorimat @mposolda Please try to do a refresh review. I think that now this is more complete and we can continue the same idea in the rest of the username authenticators.

@mposolda
Copy link
Contributor
mposolda commented Jun 4, 2025

@rmartinc @tnorimat @Romain7495 Thanks everyone for the review and testing!

For me, passkeys work as expected on Ubuntu 24.04 and Chrome 136 and Google phone 8. The Firefox does not work for me on Ubuntu, however Firefox does not work also with https://www.passkeys.io/ as well. With Firefox, I can only use yubikey as 2nd-factor authenticator for WebAuthn (no user saved on passkeys, just a default setup of WebAuthn policy used for 2nd-factor authentication).

I hope to merge tomorrow morning CET time (around 12 hours from now). @tnorimat @Romain7495 Please tell me if you want to re-review and re-test this PR and you want more time. I will wait with merging if you let me know and want more time for review and test. Otherwise I hope to merge.

@Romain7495
Copy link
Contributor
Romain7495 commented Jun 4, 2025

@mposolda Thanks for the update. Everything looks good based on my testing.

Tested on macOS (Apple M4):

  • Safari 18.5 (20621.2.5.11.8): Conditional UI and passkey sign-in work as expected.
  • Chrome 136.0.7103.114 (arm64): Conditional UI and passkey sign-in work.
  • Firefox 139.0.1 (aarch64): Got a prompt to allow access to passkeys; then both Conditional UI and sign-in with passwordless passkeys worked fine.
SCR-20250605-bajg

Note: Mobile testing is limited without HTTPS (required for WebAuthn except on localhost).
Tried with ngrok, no luck. Got this message when testing without SSL on a private IP (http://192.168.x.x):

error="not_allowed", web_authn_authentication_error="webauthn-error-api-get", web_authn_authentication_error_detail="WebAuthn is not supported by this browser. Try another one or contact your administrator."

image

@mposolda
Copy link
Contributor
mposolda commented Jun 5, 2025

@Romain7495 @tnorimat Thanks for the additional reviews and the details about testing!

@mposolda mposolda merged commit 4111082 into keycloak:main Jun 5, 2025
79 of 83 checks passed
@dasniko
Copy link
Contributor
dasniko commented Jun 6, 2025

Thanks all for your work, this feature is highly appreciated!! 🙏🙏🙏
I've just tested it with the current nightly and it seems to work as expected. 👍

shawkins pushed a commit to shawkins/keycloak that referenced this pull request Jun 6, 2025
…keys isConditionalMediationAvailable (keycloak#38781)

Closes keycloak#29596

Signed-off-by: rmartinc <rmartinc@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Passkeys conditional UI: integration with username/password form
7 participants
0