Single-Sign-On in Camunda

Hi all,

I’m currently evaluating OpenAM as a Single-Sign-On server to use together with Camunda. I found a post on the Google forum about SSO, but am not able to get it to work. I changed the web.xml file as described in web.xml. I used the AuthenticationFilter described in AuthFilter.

The current state of my solution is the following. When I go to the camunda web app I get redirected to the OpenAM portal. I can login, get redirected again (on successful login) back to the camunda web app. So far so good, but then Camunda returns a 403 Forbidden for the (should be authenticated) request.

By experimenting a bit, I think I narrowed my issue down to the AuthenticationFilter class. I tried to add the gist (referenced in the aforementioned forum post) as a library in the server, but failed to get it to work.

Does anyone have any additional information about how to do SSO in Camunda or even about the OpenAM solution? Is there any additional documentation available, besides the forum post, to set up SSO on Camunda BPM? Are there any suggestions to which SSO software to use?

Thank you in advance.

Kind regard

Pieter

3 Likes

Hi Pieter,

Are you talking about the regular process apps or the camunda webapp (cockpit / tasklist) ?

In the webapp case:
Sounds like your SSO authentication works correctly and the problem ist “just” the expected authentication information from the camunda webapp.
Please check if your AuthenticationFilter correctly maps the expected roles () into the “Authentications” object.

    private void mapAuthenticationInformationToCamunda(final HttpSession session, String username, Set<String> roles) {
        Set<String> allowedWebapps = new HashSet<String>(Arrays.asList("admin", "cockpit", "tasklist"));

        final UserAuthentication auth = new UserAuthentication(username, new ArrayList<String>(roles), CAMUNDA_PROCESS_ENGINE_NAME, allowedWebapps);

        Authentications authentications = Authentications.getFromSession(session);
        authentications.addAuthentication(auth);
    }

Hope this helps,

Lars

Hi Lars,

First of all thank you for your response and offered help :wink:

I am talking about a webapp (engine-rest). I would like to use single-sign-on in / on top of Camunda BPM.

One of the issues I had with implementing the AuthenticationFilter is using the Authentications class. Should I change the authentication filter inside the engine-rest application or can I add a custom filter as a Java library and just reference it in the web.xml file? I actually tried both and failed. I assume there should be an easy way to add this functionality to Camunda BPM?

When I have time, I will verify whether your solution works, but I expect to have the same issues as I assume I need to import the Authentications class the same way I did before.

Kind regards

Pieter

Hi,

did you see the JBoss/AD SSO community extension? Maybe it does something similar?

Cheers,
Sebastian

Hi Sebastian,

Thank you for your response. I indeed checked the extension. This does unfortunately tightly integrate JBoss and AD, which is really specific. This is not what I want. I would like a solution that can be more loosely coupled and is usable for most relevant user stores.

Kind regards

Pieter

Hi Pieter,

We have two filters for our SSO solution.

  1. org.springframework.web.filter.DelegatingFilterProxy (named springSecurityFilterChain)
    The standard Spring Filter doing the SSO stuff and supplying the logged-in user-details via the SecurityContextHolder
  2. SpringToCamundaMappingFilter
    This one was specifically to map the SecurityContextHolder-Information to the camunda-Authentications object. (containing the method posted above).

Anyways good luck, this isn’t the easiest thing to debug :slightly_smiling:

Lars

1 Like

Hi,

might I suggest an alternative route: create a plugin. I’ve been checking out ways to add custom REST-logging, and within camunda the plugin resource classes are added to the Application ‘on the inside’. A quick security-hack seems to be working:

@Provider
@ServerInterceptor
public class RestSecurityInterceptor implements PreProcessInterceptor {

  private static final Logger LOGGER = Logger.getLogger(RestSecurityInterceptor.class.getName());

  private static final String[] APPS = new String[] { "cockpit", "tasklist" };

  @Context
  private HttpServletRequest servletRequest;  
  
    public ServerResponse preProcess(final HttpRequest httpRequest, final ResourceMethod resourceMethod)
            throws Failure, WebApplicationException {
      
      Authentications authentications = Authentications.getFromSession(servletRequest.getSession());
      if(!authentications.hasAuthenticationForProcessEngine("default")) {
        LOGGER.info("Add authentication");
        
        Set<String> authorizedApps = new HashSet<String>();
        
        Collections.addAll(authorizedApps, APPS);
        
        UserAuthentication userAuthentication = new UserAuthentication("demo", Arrays.asList("admin"), "default", authorizedApps);
        
        authentications.addAuthentication(userAuthentication);
        Authentications.setCurrent(authentications);
  
        Authentications.updateSession(servletRequest.getSession(), authentications);
        
        LOGGER.info("Added security context " + authentications);
      } else {
        LOGGER.info("Already authenticated " + authentications.getAuthentications());
      }
        
      return null;
    }

}

Best regards,
Thomas

Hi,
I am trying to write a Custom Authentication filter and make the entry in Web.xml of the Web Project.
So that the user need not login into Camunda again while navigating from my application.
Details:

Camunda version: Tomcat 7.4.0
Deploying the Camunda library directly into Tomcat lib with a bundled Camunda components

Now, I want to override the Camunda Authentication and set the Auth Object within Camunda using my filter.

Issues:

Issue 1> I am unable to find the POM dependency to compile the file
Can anyone please help me find the POM entry for below classes?

import org.camunda.bpm.webapp.impl.security.SecurityActions;
import org.camunda.bpm.webapp.impl.security.SecurityActions.SecurityAction;
import org.camunda.bpm.webapp.impl.security.auth.Authentication;
import org.camunda.bpm.webapp.impl.security.auth.Authentications;
import org.camunda.bpm.webapp.impl.security.auth.UserAuthentication;

Issue 2 > Not sure if building this Filter seperately and copying into server lib will solve my problem.
Or do I have to rebuild the Camunda source with this?

1 Like

Hi all,

I think I might have found a (relative) simple solution to this problem. It does require custom implementation but I expect I will work (did not have time to test it yet).

As per the documentation here you can easily change the authentication mechanism (for the engine-rest app). By implementing a class that implements the org.camunda.bpm.engine.rest.security.auth.AuthenticationProvider interface, you should be able to provide authentication details. An example implementation is provided by Camunda (Basic authentication implementation). You could provide your own implementation, add it to the web.xml (as described in the basic auth example) and all requests should be authenticated using your implementation.

This does only solve the authentication part of the issue, but it is a start? Authorization details still need to be provided in Camunda itself. (Usernames and groups need to exist)

If anyone has any remarks or any experience with this approach, sharing is caring ;).

P.s. @rohansshetty7: Is this what you are trying to do?

Kind regards

Pieter

Thanks Pieter for you input.

Yes what you explained will be more or less what I am looking for in case of Camunda Rest API.

In addition I am also trying to implement SSO for Webapp Tasklist Application.
Here I am plugging in my Custom filter and making the change in the Web.xml to point to my filter.

Within that Filter (Code is as per Filter here). I am trying to call a WebService to authenticate whether User has valid live session and if yes then go ahead with populating the “setKnownPrinicipal” otherwise just return.

Hope this is the right way to do it.

Hi,

I was using Filter and adding filter with “camunda-auth” and ProcessEngineAuthenticationFilter.class for login and I can able to login using Http protocol but I need to use a secured login using Https where Is it possible to login using secured way using token based authentication by spring-security. Please provide feasible solution for this.

Thanks in advance.

(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)

@Pieter_Vincken did you make further progress on this?

I am wondering any progress here

Me too, :sob: , any progress here?

Hi guys,

The approach I described in my previous post worked. We have a working custom authentication platform. We now have a solution using JWTs to authenticate the user and authenticate them in the engine (using the Identity API).

Since we only use the REST API of Camunda, I have no experience towards getting this approach to work with Camunda Tasklist.

Kind regards

Pieter

Hi @Pieter_Vincken,

In your previous post, you mention that the authorization details (group associations etc.) need to exist in Camunda for the AuthenticationProvider implementation to work. And it’s evident from how the HttpBasicAuthenticationProvider is implemented, Camunda uses the identityService’s password verification to create the AuthenticationResult.
So how actually would you suggest the custom authentication should work? I guess during authentication, Camunda relies on the UserAuthentication object as well, doesn’t it?

We too are trying to hook-in a custom authentication provider to the REST APIs, based on OpenId-Connect (using our own Identity Provider), but can’t figure out the following:

  • If we create a custom filter to intercept all calls and populate the UserAuthentication object to be set to the the session object (Authentications), how the internal calls to the identityService implementation would then be handled?

  • If we go by implementing the AuthenticationProvider, we would still need a way to make the users known to the identityService too for authorizations to be handled. No? How would you suggest the identityService should be implemented then?

Any help would be much appreciated.

Thanks in advance.

Hi @Ashutosh,

The authorization details indeed need to exists within Camunda BPM. We actually decode the JWT in the authentication provider and obtain all necessary data from that object (username and groups) and create memberships on the fly if needed.

We do not implement a completely custom filter. We reused the one from the example and changed it to what we needed. Instead of checking the basic authentication details with the data in the Camunda Engine, we decode the JWT from the request and add all authentication details to the engine. We create the user if necessary and add any non-existing memberships. Finally we create a “successfull authentication” (sorry don’t remember the classname and method by heart).

The authorization details would already exist within the engine. This would be provided by the process implementation. Candidate groups, candidate users, etc are used to authorize the users in the engine. We do not implement a custom authorization service. Camunda still authorizes our calls, we only provide a custom authentication.

Hope this was somewhat clear / useful.

Kind regards,

Pieter Vincken

Is there any progress in this topic?

What i would suggest is to move class org.camunda.bpm.engine.rest.security.auth.AuthenticationProvider to any common jar outside engine-rest.
I this case we could develop custom provider (which extends AuthenticationProvider interface) in external jar and override web.xml with custom provider. That’s it!
Could someone do it? Please!

Erki

1 Like

Example about my JWT provider and filter.

First we need to build custom jar and copy it to Camunda lib folder.
Camunda jar contains following files: filter, provider and customized AuthenticationResult.

JwtAuthenticationProvider.java.txt (3.5 KB)
AuthenticationResultWithGroups.java.txt (620 Bytes)
JwtEngineAuthenticationFilter.java.txt (3.8 KB)

After that some other libraries are required too. Copy following libraries to Camunda lib:
camunda-engine-rest-core-7.7.0.jar, jjwt-0.8.0.jar, jackson-databind-2.6.3.jar, jackson-core-2.6.3.jar, jackson-annotations-2.8.9.jar

And finally override Camunda engine-rest.war web.xml with following rows:

  <filter>
    <filter-name>camunda-auth</filter-name>
    <filter-class>
      org.hunt.kriimsilm.camunda.jwt.JwtEngineAuthenticationFilter
    </filter-class>
    <init-param>
      <param-name>authentication-provider</param-name>
      <param-value>org.hunt.kriimsilm.camunda.jwt.JwtAuthenticationProvider</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>camunda-auth</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

And ensure that all required group IDs + permissions are in Camunda “act_ru_authorization” tabel.

Erki

1 Like