feat: pass totpSecretKeyUri to the totp template#50122
Open
whawker wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR exposes the canonical otpauth:// TOTP key URI to the login-config-totp FreeMarker model as totp.totpSecretKeyUri, so themes can render it (e.g., as a deep link on mobile) without reconstructing the URI client-side.
Changes:
- Added
TotpUtils.keyUri(...)to build and reuse the same key URI that is embedded in the QR code. - Added
totpSecretKeyUritoTotpBean(new getter for template access). - Added unit tests covering issuer fallback behavior and bean exposure of the key URI.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| services/src/main/java/org/keycloak/utils/TotpUtils.java | Introduces keyUri(...) and reuses it from qrCode(...) to centralize key-URI construction. |
| services/src/main/java/org/keycloak/forms/login/freemarker/model/TotpBean.java | Exposes totpSecretKeyUri on the FreeMarker model so templates can access the otpauth:// URI directly. |
| services/src/test/java/org/keycloak/utils/TotpUtilsTest.java | Adds tests for issuer selection/fallback behavior in TotpUtils.keyUri(...). |
| services/src/test/java/org/keycloak/forms/login/freemarker/model/TotpBeanTest.java | Adds tests verifying the bean exposes the correct key URI and its expected components. |
Comment on lines
75
to
+77
| this.totpSecretEncoded = TotpUtils.encode(totpSecret); | ||
| this.totpSecretQrCode = TotpUtils.qrCode(session, totpSecret, realm, user); | ||
| this.totpSecretKeyUri = TotpUtils.keyUri(session, totpSecret, realm, user); |
Signed-off-by: Will Hawker <whawker@users.noreply.github.com>
6936121 to
75e8fff
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Exposes the
otpauth://key URI (the same URI that is already encoded into the TOTP QR code) directly to thelogin-config-totptemplate via a newtotp.totpSecretKeyUriattribute.Why
During a setup TOTP flow, if you're already using your mobile device, you can't scan the QR code on your screen. If we instead offer the URI as a clickable link it will open in their chosen authenticator application, asking if the user wants to add the secret key.
This change surfaces that existing URI so custom themes can render it (e.g. as a tappable link on mobile), without having to reconstruct it client-side from the secret, issuer, algorithm, digits and period.
Security considerations
The key URI contains the shared TOTP secret in plaintext — but this exposes nothing new: the same secret is already present on the same page, in the QR image (which is the encoded URI) and in the existing
${totp.totpSecret}hidden form field sent to the same client. No additional data leaves the server.AI usage disclosure
Parts of this contribution (the
TotpUtils/TotpBeanaccompanying tests) were created with the assistance of an AI coding agent.