From 70ff0b5c5cdd449b93d95428675278a0a1277cfb Mon Sep 17 00:00:00 2001 From: Brian Long Date: Fri, 1 Jul 2022 12:06:30 -0400 Subject: [PATCH] added APS v2.x compatibility --- pom.xml | 16 +- .../KeycloakActivitiEngineAuthenticator.java | 162 ------------------ 2 files changed, 11 insertions(+), 167 deletions(-) delete mode 100644 src/main/java/com/inteligr8/activiti/keycloak/KeycloakActivitiEngineAuthenticator.java diff --git a/pom.xml b/pom.xml index 5a0a69c..08cd7a8 100644 --- a/pom.xml +++ b/pom.xml @@ -3,8 +3,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.inteligr8.activiti - keycloak-activiti-app-ext - 1.3-SNAPSHOT + keycloak-activiti-app-ext + 1.3-SNAPSHOT Keycloak Authentication & Authorization for APS @@ -12,9 +12,9 @@ 11 11 - 1.11.1.1 - 6.0.1 - 2.0.17.RELEASE + 2.3.2 + 10.0.2 + 2.5.2.RELEASE 1.7.26 @@ -37,6 +37,7 @@ ${keycloak.version} provided + com.activiti activiti-app @@ -44,6 +45,7 @@ classes provided + com.activiti activiti-app-logic @@ -53,6 +55,10 @@ + + alfresco-private + https://artifacts.alfresco.com/nexus/content/groups/private + activiti-releases https://artifacts.alfresco.com/nexus/content/repositories/activiti-enterprise-releases diff --git a/src/main/java/com/inteligr8/activiti/keycloak/KeycloakActivitiEngineAuthenticator.java b/src/main/java/com/inteligr8/activiti/keycloak/KeycloakActivitiEngineAuthenticator.java deleted file mode 100644 index 576ee35..0000000 --- a/src/main/java/com/inteligr8/activiti/keycloak/KeycloakActivitiEngineAuthenticator.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.inteligr8.activiti.keycloak; - -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.activiti.engine.IdentityService; -import org.activiti.engine.identity.Group; -import org.activiti.engine.identity.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Lazy; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.stereotype.Component; - -/** - * This is an unused implementation for non-APS installation. It is not tested - * and probably pointless. - * - * @author brian.long@yudrio.com - */ -@Component("keycloak-ext.activiti-engine.authenticator") -@Lazy -public class KeycloakActivitiEngineAuthenticator extends AbstractKeycloakActivitiAuthenticator { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Autowired - private IdentityService identityService; - - @Value("${keycloak-ext.group.prefix:KEYCLOAK_}") - private String groupPrefix; - - /** - * This method validates that the user exists, if not, it creates the - * missing user. Without this functionality, SSO straight up fails. - */ - @Override - public void preAuthenticate(Authentication auth) throws AuthenticationException { - User user = this.findUser(auth); - if (user == null) { - if (this.createMissingUser) { - this.logger.debug("User does not yet exist; creating the user: {}", auth.getName()); - - user = this.createUser(auth); - this.logger.debug("Created user: {} => {}", user.getId(), user.getEmail()); - - if (this.clearNewUserDefaultGroups) { - this.logger.debug("Clearing groups: {}", user.getId()); - List groups = this.identityService.createGroupQuery() - .groupMember(user.getId()) - .list(); - for (Group group : groups) - this.identityService.deleteMembership(user.getId(), group.getId()); - } - } else { - this.logger.info("User does not exist; user creation is disabled: {}", auth.getName()); - } - } - } - - /** - * This method validates that the groups exist, if not, it creates the - * missing ones. Without this functionality, SSO works, but the user's - * authorities are not synchronized. - */ - @Override - public void postAuthenticate(Authentication auth) throws AuthenticationException { - User user = this.findUser(auth); - this.logger.debug("Inspecting user: {} => {}", user.getId(), user.getEmail()); - - this.syncUserRoles(user, auth); - } - - private User findUser(Authentication auth) { - String email = auth.getName(); - - User user = this.identityService.createUserQuery() - .userEmail(email) - .singleResult(); - - return user; - } - - private User createUser(Authentication auth) { - User user = this.identityService.newUser(auth.getName()); - user.setEmail(auth.getName()); - this.identityService.saveUser(user); - return user; - } - - private void syncUserRoles(User user, Authentication auth) { - Map roles = this.getKeycloakRoles(auth); - if (roles == null) { - this.logger.debug("The user roles could not be determined; skipping sync: {}", user.getEmail()); - return; - } - - // check Activiti groups - List groups = this.identityService.createGroupQuery() - .groupMember(user.getEmail()) - .list(); - this.logger.debug("User is currently a member of {} groups", groups.size()); - for (Group group : groups) { - if (!group.getId().startsWith(this.groupPrefix) && this.syncInternalGroups) - continue; - - this.logger.trace("Inspecting group: {} => {} ({})", group.getId(), group.getName(), group.getType()); - if (roles.remove(this.activitiGroupIdToKeycloakRole(group.getId())) != null) { - this.logger.trace("Group and membership already exist: {} => {}", user.getEmail(), group.getName()); - // already a member of the group - } else { - if (this.syncGroupRemove) { - this.logger.trace("Group membership not in OIDC token; removing from group: {} => {}", user.getEmail(), group.getName()); - this.identityService.deleteMembership(user.getId(), group.getId()); - } else { - this.logger.debug("User/group membership sync disabled; not removing user from group: {} => {}", user.getId(), group.getId()); - } - } - } - - this.logger.debug("Unaddressed OIDC roles: {}", roles); - - // check remainder/unaddressed roles - for (Entry role : roles.entrySet()) { - this.logger.trace("Inspecting role: {}", role); - - Group group = this.identityService.createGroupQuery() - .groupId(this.keycloakRoleToActivitiGroupId(role.getKey())) - .singleResult(); - if (group == null) { - if (this.createMissingGroup) { - this.logger.trace("Group does not exist; creating one"); - group = this.identityService.newGroup(this.keycloakRoleToActivitiGroupId(role.getKey())); - group.setName(role.getValue()); - this.identityService.saveGroup(group); - } else { - this.logger.info("Group does not exist; group creation is disabled: {}", role.getKey()); - } - } - - if (group != null && this.syncGroupAdd) { - this.logger.trace("Group membership not in Activiti; adding to group: {} => {}", user.getEmail(), group.getName()); - this.identityService.createMembership(user.getId(), group.getId()); - } else { - this.logger.debug("User/group membership sync disabled; not adding user to group: {} => {}", user.getId(), group.getId()); - } - } - } - - private String keycloakRoleToActivitiGroupId(String role) { - return this.groupPrefix + role; - } - - private String activitiGroupIdToKeycloakRole(String groupId) { - return groupId.startsWith(this.groupPrefix) ? groupId.substring(this.groupPrefix.length()) : groupId; - } - -}