Loading src/main/java/com/inteligr8/activiti/ais/AbstractIdentityServiceActivitiAuthenticator.java +63 −19 Original line number Diff line number Diff line Loading @@ -2,19 +2,20 @@ package com.inteligr8.activiti.ais; import java.util.Collection; import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.OidcKeycloakAccount; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessToken.Access; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import com.activiti.security.identity.service.authentication.provider.IdentityServiceAuthenticationToken; import com.inteligr8.activiti.Authenticator; public abstract class AbstractIdentityServiceActivitiAuthenticator implements Authenticator { Loading @@ -23,33 +24,76 @@ public abstract class AbstractIdentityServiceActivitiAuthenticator implements Au protected AccessToken getOidcAccessToken(Authentication auth) { protected Set<String> getRoles(Authentication auth) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("Auto-parsed authorities: {}", authorities); if (authorities.isEmpty()) { AccessToken atoken = this.getKeycloakAccessToken(auth); if (atoken == null) { this.logger.debug("Access token not available"); return null; } else if (atoken.getRealmAccess() == null && atoken.getResourceAccess().isEmpty()) { this.logger.debug("Access token has no role information"); return null; } else { if (atoken.getRealmAccess() != null) { this.logger.debug("Access token realm roles: {}", atoken.getRealmAccess().getRoles()); authorities.addAll(atoken.getRealmAccess().getRoles()); } for (Entry<String, Access> resourceAccess : atoken.getResourceAccess().entrySet()) { this.logger.debug("Access token resources '{}' roles: {}", resourceAccess.getKey(), resourceAccess.getValue().getRoles()); authorities.addAll(resourceAccess.getValue().getRoles()); } this.logger.debug("Access token authorities: {}", authorities); } } return authorities; } protected AccessToken getKeycloakAccessToken(Authentication auth) { KeycloakSecurityContext ksc = this.getKeycloakSecurityContext(auth); return ksc.getToken(); return ksc == null ? null : ksc.getToken(); } @SuppressWarnings("unchecked") protected KeycloakSecurityContext getKeycloakSecurityContext(Authentication auth) { if (auth instanceof KeycloakAuthenticationToken) { this.logger.debug("Fetching KeycloakSecurityContext from KeycloakAuthenticationToken"); if (auth.getPrincipal() instanceof KeycloakPrincipal) { if (auth.getCredentials() instanceof KeycloakSecurityContext) { this.logger.debug("Found keycloak context in credentials"); return (KeycloakSecurityContext)auth.getCredentials(); } else if (auth.getPrincipal() instanceof KeycloakPrincipal) { this.logger.debug("Found keycloak context in principal: {}", auth.getPrincipal()); return ((KeycloakPrincipal<? extends KeycloakSecurityContext>)auth.getPrincipal()).getKeycloakSecurityContext(); } else { } else if (!(auth instanceof KeycloakAuthenticationToken)) { this.logger.warn("Unexpected token: {}", auth.getClass()); return null; } } else if (auth instanceof IdentityServiceAuthenticationToken) { this.logger.debug("Fetching KeycloakSecurityContext from IdentityServiceAuthenticationToken"); OidcKeycloakAccount account = ((IdentityServiceAuthenticationToken)auth).getAccount(); return account == null ? null : account.getKeycloakSecurityContext(); KeycloakAuthenticationToken ktoken = (KeycloakAuthenticationToken)auth; if (ktoken.getAccount() != null) { this.logger.debug("Found keycloak context in account: {}", ktoken.getAccount().getPrincipal() == null ? null : ktoken.getAccount().getPrincipal().getName()); return ktoken.getAccount().getKeycloakSecurityContext(); } else { this.logger.warn("Unable to find keycloak security context"); this.logger.debug("Principal: {}", auth.getPrincipal()); this.logger.debug("Account: {}", ktoken.getAccount()); if (auth.getPrincipal() != null) this.logger.debug("Principal type: {}", auth.getPrincipal().getClass()); return null; } } protected Set<String> toSet(Collection<? extends GrantedAuthority> grantedAuthorities) { Set<String> authorities = new HashSet<>(grantedAuthorities.size()); for (GrantedAuthority grantedAuthority : grantedAuthorities) authorities.add(grantedAuthority.getAuthority()); Set<String> authorities = new HashSet<>(Math.max(grantedAuthorities.size(), 16)); for (GrantedAuthority grantedAuthority : grantedAuthorities) { String authority = StringUtils.trimToNull(grantedAuthority.getAuthority()); if (authority == null) this.logger.warn("The granted authorities include an empty authority!?: '{}'", grantedAuthority.getAuthority()); authorities.add(authority); } return authorities; } } src/main/java/com/inteligr8/activiti/ais/IdentityServiceActivitiAppAuthenticator.java +7 −4 Original line number Diff line number Diff line Loading @@ -148,9 +148,9 @@ public class IdentityServiceActivitiAppAuthenticator extends AbstractIdentitySer } private User createUser(Authentication auth, Long tenantId) { AccessToken atoken = this.getOidcAccessToken(auth); AccessToken atoken = this.getKeycloakAccessToken(auth); if (atoken == null) { this.logger.debug("The OIDC access token could not be found; using email to determine names: {}", auth.getName()); this.logger.debug("The keycloak access token could not be found; using email to determine names: {}", auth.getName()); Matcher emailNamesMatcher = this.emailNamesPattern.matcher(auth.getName()); if (!emailNamesMatcher.matches()) { this.logger.warn("The email address could not be parsed for names: {}", auth.getName()); Loading @@ -166,8 +166,11 @@ public class IdentityServiceActivitiAppAuthenticator extends AbstractIdentitySer } private void syncUserAuthorities(User user, Authentication auth, Long tenantId) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("OIDC authorities: {}", authorities); Set<String> authorities = this.getRoles(auth); if (authorities == null) { this.logger.debug("The user authorities could not be determined; skipping sync: {}", user.getEmail()); return; } // check Activiti groups User userWithGroups = this.userService.findUserByEmailFetchGroups(user.getEmail()); Loading src/main/java/com/inteligr8/activiti/ais/IdentityServiceActivitiEngineAuthenticator.java +5 −2 Original line number Diff line number Diff line Loading @@ -106,8 +106,11 @@ public class IdentityServiceActivitiEngineAuthenticator extends AbstractIdentity } private void syncUserAuthorities(User user, Authentication auth) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("OIDC authorities: {}", authorities); Set<String> authorities = this.getRoles(auth); if (authorities == null) { this.logger.debug("The user authorities could not be determined; skipping sync: {}", user.getEmail()); return; } // check Activiti groups List<Group> groups = this.identityService.createGroupQuery() Loading Loading
src/main/java/com/inteligr8/activiti/ais/AbstractIdentityServiceActivitiAuthenticator.java +63 −19 Original line number Diff line number Diff line Loading @@ -2,19 +2,20 @@ package com.inteligr8.activiti.ais; import java.util.Collection; import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.OidcKeycloakAccount; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessToken.Access; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import com.activiti.security.identity.service.authentication.provider.IdentityServiceAuthenticationToken; import com.inteligr8.activiti.Authenticator; public abstract class AbstractIdentityServiceActivitiAuthenticator implements Authenticator { Loading @@ -23,33 +24,76 @@ public abstract class AbstractIdentityServiceActivitiAuthenticator implements Au protected AccessToken getOidcAccessToken(Authentication auth) { protected Set<String> getRoles(Authentication auth) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("Auto-parsed authorities: {}", authorities); if (authorities.isEmpty()) { AccessToken atoken = this.getKeycloakAccessToken(auth); if (atoken == null) { this.logger.debug("Access token not available"); return null; } else if (atoken.getRealmAccess() == null && atoken.getResourceAccess().isEmpty()) { this.logger.debug("Access token has no role information"); return null; } else { if (atoken.getRealmAccess() != null) { this.logger.debug("Access token realm roles: {}", atoken.getRealmAccess().getRoles()); authorities.addAll(atoken.getRealmAccess().getRoles()); } for (Entry<String, Access> resourceAccess : atoken.getResourceAccess().entrySet()) { this.logger.debug("Access token resources '{}' roles: {}", resourceAccess.getKey(), resourceAccess.getValue().getRoles()); authorities.addAll(resourceAccess.getValue().getRoles()); } this.logger.debug("Access token authorities: {}", authorities); } } return authorities; } protected AccessToken getKeycloakAccessToken(Authentication auth) { KeycloakSecurityContext ksc = this.getKeycloakSecurityContext(auth); return ksc.getToken(); return ksc == null ? null : ksc.getToken(); } @SuppressWarnings("unchecked") protected KeycloakSecurityContext getKeycloakSecurityContext(Authentication auth) { if (auth instanceof KeycloakAuthenticationToken) { this.logger.debug("Fetching KeycloakSecurityContext from KeycloakAuthenticationToken"); if (auth.getPrincipal() instanceof KeycloakPrincipal) { if (auth.getCredentials() instanceof KeycloakSecurityContext) { this.logger.debug("Found keycloak context in credentials"); return (KeycloakSecurityContext)auth.getCredentials(); } else if (auth.getPrincipal() instanceof KeycloakPrincipal) { this.logger.debug("Found keycloak context in principal: {}", auth.getPrincipal()); return ((KeycloakPrincipal<? extends KeycloakSecurityContext>)auth.getPrincipal()).getKeycloakSecurityContext(); } else { } else if (!(auth instanceof KeycloakAuthenticationToken)) { this.logger.warn("Unexpected token: {}", auth.getClass()); return null; } } else if (auth instanceof IdentityServiceAuthenticationToken) { this.logger.debug("Fetching KeycloakSecurityContext from IdentityServiceAuthenticationToken"); OidcKeycloakAccount account = ((IdentityServiceAuthenticationToken)auth).getAccount(); return account == null ? null : account.getKeycloakSecurityContext(); KeycloakAuthenticationToken ktoken = (KeycloakAuthenticationToken)auth; if (ktoken.getAccount() != null) { this.logger.debug("Found keycloak context in account: {}", ktoken.getAccount().getPrincipal() == null ? null : ktoken.getAccount().getPrincipal().getName()); return ktoken.getAccount().getKeycloakSecurityContext(); } else { this.logger.warn("Unable to find keycloak security context"); this.logger.debug("Principal: {}", auth.getPrincipal()); this.logger.debug("Account: {}", ktoken.getAccount()); if (auth.getPrincipal() != null) this.logger.debug("Principal type: {}", auth.getPrincipal().getClass()); return null; } } protected Set<String> toSet(Collection<? extends GrantedAuthority> grantedAuthorities) { Set<String> authorities = new HashSet<>(grantedAuthorities.size()); for (GrantedAuthority grantedAuthority : grantedAuthorities) authorities.add(grantedAuthority.getAuthority()); Set<String> authorities = new HashSet<>(Math.max(grantedAuthorities.size(), 16)); for (GrantedAuthority grantedAuthority : grantedAuthorities) { String authority = StringUtils.trimToNull(grantedAuthority.getAuthority()); if (authority == null) this.logger.warn("The granted authorities include an empty authority!?: '{}'", grantedAuthority.getAuthority()); authorities.add(authority); } return authorities; } }
src/main/java/com/inteligr8/activiti/ais/IdentityServiceActivitiAppAuthenticator.java +7 −4 Original line number Diff line number Diff line Loading @@ -148,9 +148,9 @@ public class IdentityServiceActivitiAppAuthenticator extends AbstractIdentitySer } private User createUser(Authentication auth, Long tenantId) { AccessToken atoken = this.getOidcAccessToken(auth); AccessToken atoken = this.getKeycloakAccessToken(auth); if (atoken == null) { this.logger.debug("The OIDC access token could not be found; using email to determine names: {}", auth.getName()); this.logger.debug("The keycloak access token could not be found; using email to determine names: {}", auth.getName()); Matcher emailNamesMatcher = this.emailNamesPattern.matcher(auth.getName()); if (!emailNamesMatcher.matches()) { this.logger.warn("The email address could not be parsed for names: {}", auth.getName()); Loading @@ -166,8 +166,11 @@ public class IdentityServiceActivitiAppAuthenticator extends AbstractIdentitySer } private void syncUserAuthorities(User user, Authentication auth, Long tenantId) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("OIDC authorities: {}", authorities); Set<String> authorities = this.getRoles(auth); if (authorities == null) { this.logger.debug("The user authorities could not be determined; skipping sync: {}", user.getEmail()); return; } // check Activiti groups User userWithGroups = this.userService.findUserByEmailFetchGroups(user.getEmail()); Loading
src/main/java/com/inteligr8/activiti/ais/IdentityServiceActivitiEngineAuthenticator.java +5 −2 Original line number Diff line number Diff line Loading @@ -106,8 +106,11 @@ public class IdentityServiceActivitiEngineAuthenticator extends AbstractIdentity } private void syncUserAuthorities(User user, Authentication auth) { Set<String> authorities = this.toSet(auth.getAuthorities()); this.logger.debug("OIDC authorities: {}", authorities); Set<String> authorities = this.getRoles(auth); if (authorities == null) { this.logger.debug("The user authorities could not be determined; skipping sync: {}", user.getEmail()); return; } // check Activiti groups List<Group> groups = this.identityService.createGroupQuery() Loading