LoginPreActions.groovy
4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import javax.servlet.http.HttpServletRequestWrapper
import org.keycloak.KeycloakSecurityContext
import org.keycloak.AuthorizationContext
import org.keycloak.representations.AccessToken
import org.keycloak.representations.IDToken
import org.keycloak.adapters.KeycloakDeployment
import org.keycloak.adapters.KeycloakDeploymentBuilder
import org.keycloak.adapters.AdapterDeploymentContext
import org.keycloak.adapters.AuthenticatedActionsHandler
import org.keycloak.adapters.KeycloakConfigResolver
import org.keycloak.adapters.NodesRegistrationManagement
import org.keycloak.adapters.PreAuthActionsHandler
import org.keycloak.adapters.spi.AuthChallenge
import org.keycloak.adapters.spi.AuthOutcome
import org.keycloak.adapters.spi.InMemorySessionIdMapper
import org.keycloak.adapters.spi.SessionIdMapper
import org.keycloak.adapters.spi.UserSessionManagement
import org.keycloak.adapters.servlet.OIDCServletHttpFacade
import org.keycloak.adapters.servlet.OIDCFilterSessionStore
import org.keycloak.adapters.servlet.FilterRequestAuthenticator
def cache = ec.getCache().getCache('moqui-keycloak:deployment')
def keycloakJsonUrl = 'component://moqui-keycloak/config/moqui-keycloak.json'
def keycloakDeployment = cache.get(keycloakJsonUrl)
def idMapper = cache.get('SessionIdMapper')
if (idMapper == null) {
idMapper = new InMemorySessionIdMapper()
cache.put('SessionIdMapper', idMapper)
idMapper = cache.get('SessionIdMapper')
}
if (true || !keycloakDeployment) {
def configStream = ec.getResource().getLocationStream(keycloakJsonUrl)
keycloakDeployment = KeycloakDeploymentBuilder.build(configStream)
cache.put(keycloakJsonUrl, keycloakDeployment)
}
def facade = new OIDCServletHttpFacade(ec.web.request, ec.web.response)
def tokenStore = new OIDCFilterSessionStore(ec.web.request, facade, 100000, keycloakDeployment, idMapper)
def authenticator = new FilterRequestAuthenticator(keycloakDeployment, tokenStore, facade, ec.web.request, 8443)
def outcome = authenticator.authenticate()
ec.logger.info("outcome2: ${outcome}")
if (outcome == AuthOutcome.AUTHENTICATED) {
if (facade.isEnded()) {
ec.logger.info('facade has ended')
} else {
def actions = new AuthenticatedActionsHandler(keycloakDeployment, facade)
ec.logger.info("actions: ${actions}")
if (actions.handledRequest()) {
ec.logger.info("actions.handledRequest")
new Exception().printStackTrace()
//sri.stopRender()
return
} else {
//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 {
AuthChallenge challenge = authenticator.getChallenge()
ec.logger.info("challenge: ${challenge}")
if (challenge != null) {
if (challenge.challenge(facade)) {
ec.logger.info("challenge sent")
// 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}")
}