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()
//HttpServletRequestWrapper wrapper = tokenStore.buildWrapper()
//postKeycloakFilter(wrapper, response, chain)
//return
// If we get here, authentication was successful and the request wasn't handled by Keycloak actions
// Proceed to get tokens and log the user in
def ksc = ec.web.request.getAttribute(KeycloakSecurityContext.class.getName())
if (ksc == null) {
ec.logger.error("KeycloakSecurityContext not found in request after successful authentication outcome.")
// Optionally handle this error, maybe redirect to an error page
return
}
def idToken = ksc.getIdToken()
ec.logger.info("idToken: ${idToken}")
if (idToken == null) {
ec.logger.error("IDToken not found in KeycloakSecurityContext.")
// Optionally handle this error
return
}
def subject = idToken.getSubject()
ec.logger.info("subject: ${subject}")
def accessToken = ksc.getToken()
ec.logger.info("accessToken: ${accessToken}")
EntityValue userAccount = ec.entity.find('UserAccount').condition('externalUserId', subject).disableAuthz().one()
ec.logger.info("userAccount: ${userAccount}")
if (userAccount) {
//ec.user.pushUser(userAccount.username)
ec.user.internalLoginUser(userAccount.username)
ec.logger.info("Successfully logged in user ${userAccount.username} via Keycloak subject ${subject}")
} else {
ec.logger.warn("No UserAccount found for Keycloak subject ${subject}")
// Optionally handle this case, e.g., redirect to registration or show an error
}
}
}
} else {
......@@ -69,26 +103,10 @@ new Exception().printStackTrace()
if (challenge != null) {
if (challenge.challenge(facade)) {
ec.logger.info("challenge sent")
new Exception().printStackTrace()
//sri.stopRender()
// sri.stopRender() // Stop rendering if challenge was sent
return
}
}
// If no challenge was sent, maybe log or handle other outcomes
ec.logger.warn("Keycloak authentication outcome was not AUTHENTICATED and no challenge was sent. Outcome: ${outcome}")
}
def ksc = ec.web.request.getAttribute(KeycloakSecurityContext.class.getName())
def idToken = ksc.getIdToken()
ec.logger.info("idToken: ${idToken}")
def subject = idToken.getSubject()
ec.logger.info("subject: ${subject}")
def accessToken = ksc.getToken()
ec.logger.info("accessToken: ${accessToken}")
EntityValue userAccount = ec.entity.find('UserAccount').condition('externalUserId', subject).disableAuthz().one()
ec.logger.info("userAccount: ${userAccount}")
if (userAccount) {
//ec.user.pushUser(userAccount.username)
ec.user.internalLoginUser(userAccount.username)
}
......