Adding and improving WebAuthn error messages#50654
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves how WebAuthn/Passkey errors are presented to end users by mapping common browser/API and policy-related failures to dedicated, localizable message keys, while avoiding exposing raw technical exception text in the UI.
Changes:
- Replaces WebAuthn UI error strings that previously surfaced raw
{0}technical details with localized, user-friendly messages. - Introduces message-key mapping for common browser WebAuthn API error scenarios and for specific registration policy violations (AAGUID/attestation/attachment).
- Updates integration tests to assert the new end-user-facing messages.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| themes/src/main/resources/theme/base/login/messages/messages_en.properties | Updates existing WebAuthn error messages and adds new localized keys for common scenarios. |
| services/src/main/java/org/keycloak/services/messages/Messages.java | Adds new message-key constants for specific WebAuthn error cases. |
| services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java | Maps browser errors to specific message keys; introduces policy exception type carrying a localizable message key; removes technical details from UI error rendering. |
| services/src/main/java/org/keycloak/authentication/authenticators/browser/WebAuthnAuthenticator.java | Maps browser .get() errors to specific message keys and ensures UI no longer displays raw technical details. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/registration/WebAuthnOtherSettingsTest.java | Updates existing assertions and adds coverage for new browser API error-to-message mapping. |
| testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/registration/AuthAttachmentRegisterTest.java | Updates assertions to validate the new attachment mismatch end-user message. |
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.forms.BruteForceTest#testExceedMaxTemporaryLockouts |
874903d to
a4f9dfd
Compare
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.adapter.servlet.SAMLServletAdapterTest#salesPostSigPersistentTestKeycloak CI - Adapter IT Strict Cookies org.keycloak.testsuite.adapter.servlet.SAMLServletAdapterTest#salesMetadataTestKeycloak CI - Adapter IT Strict Cookies org.keycloak.testsuite.adapter.servlet.SAMLServletAdapterTest#employeeSigPostNoIdpKeyTestNoKeyNameInKeyInfoKeycloak CI - Adapter IT Strict Cookies org.keycloak.testsuite.adapter.servlet.SAMLServletAdapterTest#salesPostEncTestKeycloak CI - Adapter IT Strict Cookies |
57852b3 to
b07000e
Compare
146eba1 to
bcee042
Compare
rmartinc
left a comment
There was a problem hiding this comment.
Thanks @uzmamansoor09! Looks good but I think we can improve the situation more:
- Adding the option to pass parameters to the messages (for example to show the invalid aaguid or the invalid attachment). We can even add the original webauthn message for some of them if we consider necessary to ad the details. But for the moment it's OK. I just want to have the ability to use parameters.
- Catching the
ModelDuplicateExceptionin the registration class and creating another specific error for the duplcate device as before. - I think we can remove a lot of the warning messages you are adding because the event is already showing the previous detailed message. You can remove or change to debug all of them.
I have create a new commit named test in this branch: https://github.com/rmartinc/keycloak/tree/refs/heads/pr-50654 (I'm passing the CI now in GitHub, but locally the webauthn jobs passed OK). You can cherry-pick this commit and tune or change it as you want. I wanted to test if we can pass parameters to improve the messages. This gives us more freedom to create better messages for the future if needed.
|
Hi! Would be also good to check this PR that also improves the error message and provides the i18n ability: #51012 It'd be good to think about the possibility of localizing the messages and decide whether the PR should be a follow-up, or it should somehow influence this PR. Thanks! I'll do the actual review later. |
Signed-off-by: uzmamansoor09 <Uzma.Mansoor@ibm.com> # Conflicts: # testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnIdlessTest.java # testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/registration/AttestationConveyanceRegisterTest.java # testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/registration/AuthAttachmentRegisterTest.java
Signed-off-by: uzmamansoor09 <Uzma.Mansoor@ibm.com>
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.forms.MultipleTabsLoginTest#testLoginPageRefreshKeycloak CI - Forms IT (firefox) |
rmartinc
left a comment
There was a problem hiding this comment.
Thanks @uzmamansoor09! As we chatted the issue #44963 will be managed as a follow-up. We can use the webauthn4j exception thrown in the authentication and registration to give a different message per exception (or just the most commons exceptions). Approving and merging this one for the moment.
| result = user.credentialManager().isValid(cred); | ||
| } catch (WebAuthnException wae) { | ||
| logger.debug("WebAuthn authentication verification failed.", wae); | ||
| setErrorResponse(context, WEBAUTHN_ERROR_AUTH_VERIFICATION, wae.getMessage()); |
| } catch (WebAuthnException wae) { | ||
| if (logger.isDebugEnabled()) logger.debug(wae.getMessage(), wae); | ||
| logger.debug("WebAuthn registration failed.", wae); | ||
| setErrorResponse(context, WEBAUTHN_ERROR_REGISTRATION, wae.getMessage(), originalEventType); |
There was a problem hiding this comment.
Same here, the WebAuthnExceptioncan be used to set a more detailed message instead of the generic one. But there will be another PR for that.
Closes #22524
Improving how WebAuthn error messages are handled and displayed to the end-user.
Introducing error mapping for the most common WebAuthn error scenarios (such as user cancellation, an authenticator already being registered, operation timeouts, or blocked AAGUIDs) to individual message keys. For generic or unexpected errors, a generic message is shown instead, while the specific technical details from webauthn4j are written to the server logs.