Camunda engine does not evaluate group authorizations | keycloak sso

Hey,

i wrote my own custom rest wrapper with a function that returns all process instances (historic + running) for a process definition.

What permissions do i need to give a user to get all instances of a specific process definition?
Unless im camunda-admin the functions somehow always return a empty list.

I’ve granted the user the following permissions for the process definition READ_INSTANCE, READ_TASK, READ_HISTORY, TASK_WORK, TASK_ASSIGN, but the list is still empty. Im not using tenants.

Edit:
OriginalTitle: What permissions are required for getHistoricProcessInstance

Hi Philipp,

I guess that you are using historyService.createHistoricProcessInstanceQuery(), correct me if I am wrong.

I think you need only READ and READ_HISTORY. Could you try again with those?

Best regards,
Yana

1 Like

Hi Yana,

you’r right i do - and thanks for the response. I wasn’t sure if READ on the Definition also means that you can read all instances of said definitions, but that is great.

Im a little lost though because i have another issue, which is the real culprit.
I have created a filter + provider to take users/groups from keycloak and create them in camunda on-the-fly (WebApps + EngineRest) to support single-sign-on via OpenIDConnect.

I create the group and group membership in the database and set the Authorization. I attached the code snippets for this, the Keycloak Class just does all the parsing.

Somehow only authorizations set for the camunda-admin group are actually effective while all other authorizations for groups the user is a member in are ignored.
I think my issue is related to the custom auth method, even if i grant the group test full access to all resources and add my test user as member the permissions aren’t effective.

Does anyone have a idea what could cause this?

WebApps

public class KeycloakAuthenticationFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {

        final HttpServletRequest req = (HttpServletRequest) request;

        // get authentication from session
        Authentications authentications = Authentications.getFromSession(req.getSession());

        // Manipulate the default AuthenticationFilter to handle SSO
        setSSOAuthentication(request, authentications);

        // set current authentication
        Authentications.setCurrent(authentications);

        try {

            SecurityActions.runWithAuthentications(new SecurityAction<Void>() {
                public Void execute() {
                    try {
                        chain.doFilter(request, response);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    return null;
                }
            }, authentications);
        } finally {
            Authentications.clearCurrent();
            Authentications.updateSession(req.getSession(), authentications);
        }

    }

    protected void clearProcessEngineAuthentications(Authentications authentications) {

    }

    public void destroy() {

    }

    /**
     * Handle KeyCloak SSO
     */
    protected void setSSOAuthentication(final ServletRequest request, Authentications authentications) {
        Keycloak keycloak = new Keycloak(request);

        // if already in the list of logged in users - nothing to do (only for frontend / authentications.isPresent)
        Authentication authentication = authentications.getAuthenticationForProcessEngine(keycloak.getProcessEngine().getName());
        if (authentication != null && keycloak.getUserNameFromRequest().isPresent() && authentication.getName().equals(keycloak.getUserNameFromRequest().get())) {
            return;
        }
        
        // Process Token Information
        keycloak.process();
        
        // create new authentication object to store authentication
        List<String> groupIds = new ArrayList<String>();
        groupIds.addAll(keycloak.getCurrentUserRoles());
        List<String> tenantIds = new ArrayList<String>();
        tenantIds.addAll(keycloak.getCurrentUserTenants());
        UserAuthentication newAuthentication = new UserAuthentication(keycloak.getCurrentUser().get().getId(), keycloak.getProcessEngine().getName());
        newAuthentication.setGroupIds(groupIds);
        newAuthentication.setTenantIds(tenantIds);
        newAuthentication.setAuthorizedApps(keycloak.getCurrentUserAuthorizedApps());

        // and add the new logged in user
        authentications.addAuthentication(newAuthentication);
    }

}

REST

@Override
    public AuthenticationResult extractAuthenticatedUser(HttpServletRequest request, ProcessEngine engine) {
        try {
            Keycloak keycloak = new Keycloak(request);
            keycloak.setProcessEngine(engine);
            keycloak.process();
            
            if(keycloak.getCurrentUserRoles().contains("camunda-api")) {
                return AuthenticationResult.successful(keycloak.getCurrentUser().get().getId());
            } else {
                return AuthenticationResult.unsuccessful(keycloak.getCurrentUser().get().getId());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return AuthenticationResult.unsuccessful();
        }
    }

Nevermind, i had a tenant-id in my process-archive processes.xml that i didn’t remove after testing

Thanks for helping, the recommended permissions work. :slight_smile:

Cool that you managed to resolve your issue.

Hi Philip,

I am trying to integrate Camunda with Keycloak as SSO. I am also trying the same kind of approach.

I wanted to know extractAuthenticatedUser function is written in Keycloak or Camunda.

Could you please provide the Jar that contains Keycloak class or provide the import statement or the pom.xml for
Keycloak keycloak = new Keycloak(request);

Regards,
Susmita

Hey svsd,

you need to write those 2 functions in different jars that you place in tomcat/lib and include them as servlet filter within camunda and engine-rest respectively.

The keycloak class is a custom one i wrote to handle authentication.

I will create a github project for this once i find the time.

1 Like