557ca3bb by Ean Schuessler

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.
1 parent 4c6cfc8a
...@@ -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
......