Camunda in its current version is perfectly suited to run BPM in cloud infrastructures. Identity management in the cloud, however, often differs from classical approaches. Camunda already provides a generic sample for Single Sign On when using Spring Boot. See https://github.com/camunda-consulting/code/tree/master/snippets/springboot-security-sso. From my point of view this is a good starting point, but SSO is only half the story.
At https://github.com/VonDerBeck/camunda-identity-keycloak I have therefore provided a ReadOnlyIdentityProvider for Keycloak. Something similar for Auth0 is in progress. Do you think this makes sense? Any remarks? Would that be an idea for a new Community Extension?
Thank you for your contribution. The identity provider plugin is of a great help and our team has a head start. I believe Auth0 provider plugin will be of a great help to the community. One thing that i noticed is that when we integrated your Readonlyidentityprovider for keyCloak and havenāt done the SSO yet. We are using 7.10 Camunda version and getting the following error -
Caused by: java.lang.UnsupportedOperationException: This identity service implementation is read-only.
at org.camunda.bpm.engine.impl.cmd.AbstractWritableIdentityServiceCmd.execute(AbstractWritableIdentityServiceCmd.java:36) ~[camunda-engine-7.10.0.jar:7.10.0]
I see the following information. We are using Camunda Spring boot integration and so when the process engine starts, does it create a new user. Is this the reason why the readonly identity service is coming up?
Caused by: java.lang.UnsupportedOperationException: This identity service implementation is read-only.
at org.camunda.bpm.engine.impl.cmd.AbstractWritableIdentityServiceCmd.execute(AbstractWritableIdentityServiceCmd.java:36) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:27) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:106) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:45) ~[camunda-engine-spring-7.10.0.jar:7.10.0]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:43) ~[camunda-engine-spring-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:69) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.IdentityServiceImpl.newUser(IdentityServiceImpl.java:87) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.spring.boot.starter.configuration.impl.custom.CreateAdminUserConfiguration.createUser(CreateAdminUserConfiguration.java:101) ~[camunda-bpm-spring-boot-starter-3.2.0.jar:3.2.0]
at org.camunda.bpm.spring.boot.starter.configuration.impl.custom.CreateAdminUserConfiguration.postProcessEngineBuild(CreateAdminUserConfiguration.java:63) ~[camunda-bpm-spring-boot-starter-3.2.0.jar:3.2.0]
at org.camunda.bpm.engine.impl.cfg.CompositeProcessEnginePlugin.postProcessEngineBuild(CompositeProcessEnginePlugin.java:106) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.invokePostProcessEngineBuild(ProcessEngineConfigurationImpl.java:1026) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.buildProcessEngine(ProcessEngineConfigurationImpl.java:787) ~[camunda-engine-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.spring.SpringTransactionsProcessEngineConfiguration.buildProcessEngine(SpringTransactionsProcessEngineConfiguration.java:62) ~[camunda-engine-spring-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.spring.ProcessEngineFactoryBean.getObject(ProcessEngineFactoryBean.java:54) ~[camunda-engine-spring-7.10.0.jar:7.10.0]
at org.camunda.bpm.engine.spring.ProcessEngineFactoryBean.getObject(ProcessEngineFactoryBean.java:33) ~[camunda-engine-spring-7.10.0.jar:7.10.0]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
⦠152 common frames omitted
what does your configuration / application.yaml look like?
The identity provider is a ReadOnlyIdentityProvider (exactly like the LDAP Identity Provider) - therefore the engine must not create a user upon startup. If you have something like
in your configuration, this will try to create the admin user upon startup if not yet available. Please comment that out (the admin-user part). When using a ReadOnlyIdentityProvider you must create the admin user & group outside of Camunda.
I would recommend to create a Keycloak group camunda-admin and add a user assigned to this group.
You can then use the configuration attribute administratorGroupName of the plugin to make this group known to the engine.
If this is not your problem it would be very interesting to see your application.yaml.
And if this was your problem a feedback would be helpful as well - if necessary I would add a hint to the README of the plugin.
That was exactly my problem and i figured it out after couple of hours. Thanks for the information and it helps. I will try to add camunda-admin group to keycloak and it to my application.yaml file.
One more question that i have is about the SSO. I havenāt implemented the SSO yet as stated in the keyCloak Identity plugin provider. After removing the suggested demo user from the yaml file, my application ran fine. Only issue being, i canāt login with any user id although the users and groups are there in the keyCloak mainly camunda admin user.
what about your Authorizations? See chapter Authorization Management in Camunda documentation.
The admin group/user will get its authorizations automatically, for any other group / user you will have to add the access rights either manually, in some piece of startup code, or from your deployment pipeline.
What i noticed is that keycloakAdminUrl: in my yaml is the problem. The following property is wrong and this url is appended with /groups in the code which is throwing a an error 404 not found. I am using ```administratorGroupName: camunda-admin ithe yaml file.
When using the master realm this should be https://<your-keycloak-server>/auth/admin/realms/master.
Hint: the notation https://<your-keycloak-server>/auth/admin/realms/[master|<realm-name>] in the sample means āeither master or your other realm-nameā at the end of the url.
Thanks for your input, this helps to complete the docu and find other issues.
Unfortunately, the url https://<your-keycloak-server>/auth/admin/realms/master is not working in my case. My realm in keycloak is master. That is why, when /groups is appended, it is failing with 404 not found error. Just FYI.
Everything is working fine now. When i assigned āadminā to camunda-identity-service Service Account and it worked. I also noticed that administratorGroupName: camunda-admin worked and when i logged in as a user assigned to this admin group, all the OOTB applications (cockpit etc.,), I was able to see. But, if i just has administratorUserId: in yaml file, when i logged in as the user, it didnāt see any apps.
Have you used the internal Keycloak ID when configuring administratorUserId? Currently it will work only that way. Sadly username is not equal ID. Within the next update I will enhance the configuration capabilities and check for username as well because this could be a common pitfall otherwise.
Thank you for this, this is a great piece of code.
Is there a sample project configured with SSO ? Iām having trouble configuring Spring Security for both the webapps and REST APIs in the same project.
Currently I donāt have an abstract example project which already covers all aspects of SSO, even if I plan to provide one in the course of the next weeks or in the course of the summer.
When using Keycloak the only thing that changes slightly is how to extract the authenticated user / principal (which has been described in my README.md for the webapp, but should be similar for REST).
It does not yet include a full kubernetes setup - but already showcases the connection to a local running Keycloak Server. SSO setup for Cockpit/Tasklist/Admin is included. Yet missing is a more detailed description of the setup and configuration. But hope this helps anyway.
Thanks a lot ! I made it fully work (with the REST API aswell) with a bit of tuning, I changed the KeycloakAuthenticationProvider so it can detect if there is a Bearer token, if so, it extracts the user email from it and turn an AuthenticationResult
Feel free to ask the code if you want it
Iām glad to hear youāve been successful . Of course Iām interested in what you have changed and why - and would be happy if you share your changes.
Meanwhile the Showcase for the Keycloak Camunda Identity Provider Plugin contains a first basic kubernetes setup which might help you as well. Itās a quickstart, the description will improve in the future.
That is a great project you have created. We believe it would be a good fit for a community extension, so please let us know if you would like to take that step.
The transition to a community extension would involve the following:
Transferring the repository to the camunda github organization
Setting up Camunda continuous integration builds for the extension
Making the project ready to be released on Maven central
Moving the Maven coordinates into the org.camunda.bpm.extension namespace
We would take care of these steps or help you perform them.
Once a community extension, you can benefit from the following:
Releases to Maven central via the Camunda organization, so no need to deal with Maven central yourself
Possibility to publish posts on blog.camunda.org about your extension