Correct token access in LoginPreActions
Moved the logic for retrieving Keycloak tokens (ID token, subject) and logging the user into Moqui to occur only *after* the Keycloak authentication outcome is confirmed as AUTHENTICATED. Previously, the script attempted to access these tokens regardless of the authentication outcome, leading to errors (likely NullPointerException on idToken.getSubject()) when authentication failed or resulted in a challenge. This issue may have surfaced after the Keycloak upgrade to version 23. Added null checks for KeycloakSecurityContext and IDToken before accessing them.
Showing
1 changed file
with
37 additions
and
19 deletions
... | @@ -61,6 +61,40 @@ new Exception().printStackTrace() | ... | @@ -61,6 +61,40 @@ new Exception().printStackTrace() |
61 | //HttpServletRequestWrapper wrapper = tokenStore.buildWrapper() | 61 | //HttpServletRequestWrapper wrapper = tokenStore.buildWrapper() |
62 | //postKeycloakFilter(wrapper, response, chain) | 62 | //postKeycloakFilter(wrapper, response, chain) |
63 | //return | 63 | //return |
64 | |||
65 | // If we get here, authentication was successful and the request wasn't handled by Keycloak actions | ||
66 | // Proceed to get tokens and log the user in | ||
67 | def ksc = ec.web.request.getAttribute(KeycloakSecurityContext.class.getName()) | ||
68 | if (ksc == null) { | ||
69 | ec.logger.error("KeycloakSecurityContext not found in request after successful authentication outcome.") | ||
70 | // Optionally handle this error, maybe redirect to an error page | ||
71 | return | ||
72 | } | ||
73 | |||
74 | def idToken = ksc.getIdToken() | ||
75 | ec.logger.info("idToken: ${idToken}") | ||
76 | if (idToken == null) { | ||
77 | ec.logger.error("IDToken not found in KeycloakSecurityContext.") | ||
78 | // Optionally handle this error | ||
79 | return | ||
80 | } | ||
81 | |||
82 | def subject = idToken.getSubject() | ||
83 | ec.logger.info("subject: ${subject}") | ||
84 | |||
85 | def accessToken = ksc.getToken() | ||
86 | ec.logger.info("accessToken: ${accessToken}") | ||
87 | |||
88 | EntityValue userAccount = ec.entity.find('UserAccount').condition('externalUserId', subject).disableAuthz().one() | ||
89 | ec.logger.info("userAccount: ${userAccount}") | ||
90 | if (userAccount) { | ||
91 | //ec.user.pushUser(userAccount.username) | ||
92 | ec.user.internalLoginUser(userAccount.username) | ||
93 | ec.logger.info("Successfully logged in user ${userAccount.username} via Keycloak subject ${subject}") | ||
94 | } else { | ||
95 | ec.logger.warn("No UserAccount found for Keycloak subject ${subject}") | ||
96 | // Optionally handle this case, e.g., redirect to registration or show an error | ||
97 | } | ||
64 | } | 98 | } |
65 | } | 99 | } |
66 | } else { | 100 | } else { |
... | @@ -69,26 +103,10 @@ new Exception().printStackTrace() | ... | @@ -69,26 +103,10 @@ new Exception().printStackTrace() |
69 | if (challenge != null) { | 103 | if (challenge != null) { |
70 | if (challenge.challenge(facade)) { | 104 | if (challenge.challenge(facade)) { |
71 | ec.logger.info("challenge sent") | 105 | ec.logger.info("challenge sent") |
72 | new Exception().printStackTrace() | 106 | // sri.stopRender() // Stop rendering if challenge was sent |
73 | //sri.stopRender() | ||
74 | return | 107 | return |
75 | } | 108 | } |
76 | } | 109 | } |
110 | // If no challenge was sent, maybe log or handle other outcomes | ||
111 | ec.logger.warn("Keycloak authentication outcome was not AUTHENTICATED and no challenge was sent. Outcome: ${outcome}") | ||
77 | } | 112 | } |
78 | |||
79 | def ksc = ec.web.request.getAttribute(KeycloakSecurityContext.class.getName()) | ||
80 | def idToken = ksc.getIdToken() | ||
81 | ec.logger.info("idToken: ${idToken}") | ||
82 | def subject = idToken.getSubject() | ||
83 | ec.logger.info("subject: ${subject}") | ||
84 | |||
85 | def accessToken = ksc.getToken() | ||
86 | ec.logger.info("accessToken: ${accessToken}") | ||
87 | |||
88 | EntityValue userAccount = ec.entity.find('UserAccount').condition('externalUserId', subject).disableAuthz().one() | ||
89 | ec.logger.info("userAccount: ${userAccount}") | ||
90 | if (userAccount) { | ||
91 | //ec.user.pushUser(userAccount.username) | ||
92 | ec.user.internalLoginUser(userAccount.username) | ||
93 | } | ||
94 | ... | ... |
-
Please register or sign in to post a comment