Trying to use Keycloak with Camunda

Hi There. I made this repo to share my work in joining pieces. But I’m stucked in engine-rest.
Can anyone help me?

My image runs ok, but engine-rest does got up due the config changes. Have I made a mistake?

23-Sep-2020 17:57:47.407 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/camunda/webapps/engine-rest]
23-Sep-2020 17:57:56.604 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
23-Sep-2020 17:57:56.606 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
23-Sep-2020 17:57:56.607 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [/engine-rest] startup failed due to previous errors
23-Sep-2020 17:57:56.615 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/camunda/webapps/engine-rest] has finished in [9,208] ms
23-Sep-2020 16:05:22.169 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap]
	java.lang.ClassNotFoundException: org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
		at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:540)
		at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:521)
		at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4612)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5151)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
		at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1133)
		at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1867)
		at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
		at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1045)
		at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429)
		at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)
		at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
		at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
		at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
		at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:936)
		at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)
		at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:566)
		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)
23-Sep-2020 16:05:22.169 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s)



23-Sep-2020 17:57:24.282 INFO [main] org.camunda.feel.FeelEngine.<init> Engine created. [value-mapper: CompositeValueMapper(List(org.camunda.feel.impl.JavaValueMapper@2b7e8044, org.camunda.spin.plugin.impl.feel.integration.SpinValueMapper@550de6b8)), function-provider: org.camunda.bpm.dmn.feel.impl.scala.function.CustomFunctionTransformer@2db2a05f, configuration: Configuration(false)]

Thank you!

@gabepurnam check this post.

1 Like

Thanks @aravindhrs , I had read a lot of this, and made my own springboot project based on that. But what I’m trying is a straight forward base line with only adding some plugins and configs on top of Camunda Tomcat docker image.

My problem is with this part. When I add this changes, engine-rest does not startup, and the errors are above.

My config file for engine-rest is the same from ‘camunda/camunda-bpm-platform:tomcat-7.13.0’ image, but I just added this:

So, my web.xml for engine-rest became this:

My question is: If without this filter added engine-rest works, and after adding it engine-rest doesn’t works, where are the gap?

Well, lets explain my mistake. Without changing engine-rest/WEB-INF/web.xml the output was this:

24-Sep-2020 21:19:19.497 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/camunda/webapps/engine-rest]
24-Sep-2020 21:19:28.281 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
24-Sep-2020 21:19:28.377 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/camunda/webapps/engine-rest] has finished in [8,880] ms

So I copied the engine-rest/WEB-INF/web.xml from the camunda/camunda-bpm-platform:tomcat-latest, added the configs and the result was the error below:

Configs

  <!-- KeyCloak OpenID Connect Filter -->
  <filter>
    <filter-name>KeyCloak OpenID Connect Filter</filter-name>
    <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class>
    <init-param>
            <param-name>keycloak.config.file</param-name>
            <param-value>/camunda/config/keycloak.json</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>KeyCloak OpenID Connect Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
                   
  <!-- Camunda Keycloak Authentication Filter -->
  <filter>
    <filter-name>camunda-auth</filter-name>
    <filter-class>org.camunda.community.auth.keycloak.filter.KeycloakAuthenticationFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>camunda-auth</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>

Output

23-Sep-2020 17:57:47.407 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/camunda/webapps/engine-rest]
23-Sep-2020 17:57:56.604 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
23-Sep-2020 17:57:56.606 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
23-Sep-2020 17:57:56.607 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [/engine-rest] startup failed due to previous errors
23-Sep-2020 17:57:56.615 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/camunda/webapps/engine-rest] has finished in [9,208] ms

And the detailed error was this:

23-Sep-2020 16:05:22.169 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap]
	java.lang.ClassNotFoundException: org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap
		...

So, the class org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap that was not found does not exists until version 7.14.0 that, at this moment are under construction. In camunda/camunda-bpm-platform:tomcat-7.13.0 the engine-rest/WEB-INF/web.xml is this:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <!-- Fetch And Lock Handler (long polling): Unique Worker Request (default value: false) -->
  <!--
  <context-param>
    <param-name>fetch-and-lock-unique-worker-request</param-name>
    <param-value>true</param-value>
  </context-param>
  -->

  <listener>
    <listener-class>org.camunda.bpm.engine.rest.impl.FetchAndLockContextListener</listener-class>
  </listener>

  <filter>
    <filter-name>EmptyBodyFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.EmptyBodyFilter</filter-class>
    <async-supported>true</async-supported>
  </filter>
  <filter-mapping>
    <filter-name>EmptyBodyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter>
    <filter-name>CacheControlFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.CacheControlFilter</filter-class>
    <async-supported>true</async-supported>
  </filter>
  <filter-mapping>
    <filter-name>CacheControlFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- Http Basic Authentication Filter -->
  <!-- <filter>
    <filter-name>camunda-auth</filter-name>
    <filter-class>
      org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter
    </filter-class>
	<async-supported>true</async-supported>
    <init-param>
      <param-name>authentication-provider</param-name>
      <param-value>org.camunda.bpm.engine.rest.security.auth.impl.HttpBasicAuthenticationProvider</param-value>
    </init-param>
    <init-param>
	    <param-name>rest-url-pattern-prefix</param-name>
	    <param-value></param-value>
	  </init-param> 
  </filter>

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

  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>org.camunda.bpm.engine.rest.impl.application.DefaultApplication</param-value>
    </init-param>
    <async-supported>true</async-supported>
  </servlet>

  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>

Meanwhile, in camunda/camunda-bpm-platform:tomcat-latest (7.14.0) the engine-rest/WEB-INF/web.xml is this:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <!-- Fetch And Lock Handler (long polling): Unique Worker Request (default value: false) -->
  <!--
  <context-param>
    <param-name>fetch-and-lock-unique-worker-request</param-name>
    <param-value>true</param-value>
  </context-param>
  -->

  <!-- rest bootstrap listener -->
  <listener>
    <listener-class>org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap</listener-class>
  </listener>

  <listener>
    <listener-class>org.camunda.bpm.engine.rest.impl.FetchAndLockContextListener</listener-class>
  </listener>

  <filter>
    <filter-name>EmptyBodyFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.EmptyBodyFilter</filter-class>
    <async-supported>true</async-supported>
  </filter>
  <filter-mapping>
    <filter-name>EmptyBodyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter>
    <filter-name>CacheControlFilter</filter-name>
    <filter-class>org.camunda.bpm.engine.rest.filter.CacheControlFilter</filter-class>
    <async-supported>true</async-supported>
  </filter>
  <filter-mapping>
    <filter-name>CacheControlFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- Http Basic Authentication Filter -->
  <!-- <filter>
    <filter-name>camunda-auth</filter-name>
    <filter-class>
      org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter
    </filter-class>
	<async-supported>true</async-supported>
    <init-param>
      <param-name>authentication-provider</param-name>
      <param-value>org.camunda.bpm.engine.rest.security.auth.impl.HttpBasicAuthenticationProvider</param-value>
    </init-param>
    <init-param>
	    <param-name>rest-url-pattern-prefix</param-name>
	    <param-value></param-value>
	  </init-param> 
  </filter>

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

  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>org.camunda.bpm.engine.rest.impl.application.DefaultApplication</param-value>
    </init-param>
    <async-supported>true</async-supported>
  </servlet>

  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>

So, this lines are a problem to version 7.13.0

   <!-- rest bootstrap listener -->
  <listener>
    <listener-class>org.camunda.bpm.engine.rest.impl.web.bootstrap.RestContainerBootstrap</listener-class>
  </listener>

After changing that, my output result about engine-rest was this:

24-Sep-2020 21:35:06.431 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/camunda/webapps/engine-rest]
24-Sep-2020 21:35:18.426 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
24-Sep-2020 21:35:18.512 INFO [main] org.camunda.community.auth.keycloak.filter.KeycloakAuthenticationFilter.init Init KeycloakAuthenticationFilter
24-Sep-2020 21:35:18.521 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/camunda/webapps/engine-rest] has finished in [12,090] ms

Keycloak filter was enabled. 24-Sep-2020 21:35:18.512 INFO [main] org.camunda.community.auth.keycloak.filter.KeycloakAuthenticationFilter.init Init KeycloakAuthenticationFilter

Thanks a lot your work. I will improve that in my repo and want to let a easy to use repo with all basic files done, like Dockerfile, docker-compose, helm charts and helmfile.
I saw everyone trying to figure out how to do this. Putting these awesome pieces together in one place just to pick and use.

@gabepurnam thx for gathering info and making a legit great attempt on making this whole process simple for everyone. If you happen to have found other info on running a fully dockerized solution for integrating Camunda and Keycloak please let us know. Thx.

Hey @eric_lima, I really succeed using the springboot version where I modified some files, styles, images and other configs in camunda, then I generate a new image and published it in my private repo. I will check if I can update my public sample repo to help you, start following the repo to check the news. GitHub - gabepurnam/keymunda: Keymunda = Keycloak + Camunda

4 Likes

Hi @gabepurnam, thank you so much for this informative post! @VonDerBeck is the Maintainer of Keycloak. I’ve tagged him here so that you might connect if you’d like to chat with him further about GitHub - gabepurnam/keymunda: Keymunda = Keycloak + Camunda :slight_smile: and Keycloak/Spring Boot in general!

2 Likes

@kiran.oliver Thanks for getting the attention of the official maintainer to this topic. Do you think we are going to get any official distribution of an easy to deploy docker/docker-compose setup with Keycloak like other BPMN products already offer, any time soon? (I mean, I’ve checked this out and it looks great, but not so easy as a simple: docker-compose up -d as it could be. @gabepurnam got real close tho :smiling_face_with_three_hearts:)

I’m actually trying to gather info on what product would be the most suitable for our team, but SSO is a must and I really wanted to show Camunda would be the best option for us. But it’s really not working for me right now :frowning:

This is actually a surprise, as containers are one of the quickest and best ways to setup a service like this. And the Main product looks great the way it is, of course. I’ve successfuly tested camunda’s official docker image to some extent, but I really wanted to use a more suitable authentication in ours tests.

tyfyt,

Thanks for the great question @eric_lima! I think @VonDerBeck would be the best point of contact to ask regarding if we are going to get any official distribution of an easy to deploy docker/docker-compose setup with Keycloak anytime soon.

You can also perhaps open an issue with this as a feature request in the Keycloak repository as well if you’d like! Issues · camunda/camunda-bpm-identity-keycloak · GitHub

I hope this information helps!

3 Likes

Hi @eric_lima,

I understand your request. But are you aware, that anything like a simple docker-compose setup of Camunda together with Keycloak is only half of the story? It could be a help to start with that topic (actually this is what I did in the SSO example with Kubernetes…). But it will be nothing more than a quick start. Because a production setup very likely will differ in lot of ways from that. You are not going to get around learning more about cloud technologies. This has nothing to do with either Camunda or Keycloak.

Apart from that, for a good quick start: would it help to have e.g. a sample Camunda BPM Spring Boot instance together with the Keycloak Identity Provider Plugin as well as a sample Keycloak instance in one docker-compose setup? What do you expect to be better compared to the Kubernetes sample?

Regards,
Gunnar

2 Likes

I see. thanks for pointing that. I’ll expand my study case onto that.

It sure would. Thank you. I’m sure it would be useful for a lot of people as well👍

1 Like

Hi guys,
i finally found the time to update our keycloak-sso plugin (GitHub - iceman91176/camunda-bpm-auth-keycloak-sso). It is totally dockerized now, uses keycloak 11 and @VonDerBeck’s great identity-plugin.

We are running it as standalone-container for quick tests, but also in openshift and kubernetes.
Don’t hesitate to report issues…

cheers

3 Likes

As a simple quickstart I now provided a basic docker-compose setup consisting of Camunda BPM Run, the Keycloak Identity Provider Plugin and a sample Keycloak Instance with a prepared basic configuration.

See Installation on Camunda BPM Run / Docker Sample Setup. Hope this helps to better understand the very basics of the plugin configuration.

For more complex samples you have the SSO Kubernetes Showcase as well as @cbuchberger 's setup.

So the choice is yours. :wink:

Happy Easter
Gunnar

1 Like

Hi @eric_lima! I hope you’re doing well today. I just wanted to circle back with you, as the amazing @VonDerBeck and @cbuchberger have made some improvements to Keycloak that might help you to better solve your issue, which are linked in the replies above.

I hope these help, and thank you for taking a look at Camunda. Please let me know if you have any additional questions. I’m more than happy to assist however I can.