Commit 916f3712 authored by Brian Long's avatar Brian Long
Browse files

refactored a bit with fixes

parent bbef37a2
Loading
Loading
Loading
Loading
+63 −19
Original line number Diff line number Diff line
@@ -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 {
@@ -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;
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -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());
@@ -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());
+5 −2
Original line number Diff line number Diff line
@@ -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()