JWT Authentication pattern/plugin for Camunda Spring Boot and Tomcat

Hey all

I have put together a set of code based on the work from Camunda’s Authentication providers and the Camunda GraphQL jwt usage, where you can use a JWT token to authenticate with Camunda, and the Token will contain the Username, Group List and Tenant List that your action will be part of.

Anyone have use for this? We use it because of the way that we typically interact with Camunda, where Camunda is a generic microservice that does not have users other than the Admins. But in some cases we wanted to inject a user’s groups, Tenant(s), and their username so gain access to things like getCurrentUser().

This ‘plugin’ does not provide the JWT Provider, it is purely a validator of the JWT and then grabs the relevant data from the JWT and injects it into the engine’s identity service as the current logged in user.

2 Likes

Cross-Ref: Is Anyone used JWT to build custom authentication for Rest API?

Just released first commits of the plugin/library, and docker usage example

1 Like

Hello @StephenOTT,

thanks for the work. We are looking to integrate KeyCloak your solution looks promising.
You are not populating the camunda identity-database with the user that are authenticating, right ?
So you can’t use the identity-service (e.g. identityService.createUserQuery().userId(assignee).singleResult(); ) for example if you want to something like this https://github.com/camunda/camunda-bpm-examples/tree/master/usertask/task-assignment-email ?

I am thinking about the following solutions to this

  1. create some identityservice that queries keycloak for the use-cases where i need more details for assigness/groups. Building our own ReadOnlyIdentityProvider will not work here.
  2. “Syncing” users, or creating them on the fly within camunda’s identity service after succesful authentication

Solution 1 might be cleaner :wink:

1 Like

@cbuchberger thanks for reaching out!

You are not populating the camunda identity-database with the user that are authenticating, right ?

You only need to populate the Groups/Permissions within the Camunda DB. Users, Tenants are not actually required. See below for more info.

Background:

JWT plugin I created was under the premise that if you were using another system (such as keycloak) then I did not want to duplicate / sync users between two systems (~keycloak and camunda). So this plugin uses the payload provided within JWT to create a authenticated user within the session of the single request. This is basically the same thing someone would be doing with a Basic Auth request, but rather than the username/password of basic auth being authenticated against the identity DB and then doing a DB lookup for the user in question and loading that user into the current context; we just grab the user, tenants, and groups that they should be part of, from the JWT payload.

The Groups need to exist within the Camunda DB so the Camunda specific permissions can come into effect.


I like your solution one: which is some sort of intermediary class(es) that provide you the bridge to Keycloak. I dont think this needs to be a actual “Identity Service” implementation. You could just create a set of methods that provide you lookup capabilities into the keycloak http API.

@cbuchberger did you make any progress?

@StephenOTT Actually yes :wink:

I just finished the Keycloak-Validator. You can have a look here

No changes needed in your JWT REST API Validation Provider, the validator just plugs in. Authorization works like a charm.

I have not started with the part that queries Keycloak for user-information. But that should not be a big dieal.

Later

@cbuchberger great job! very exciting.

What were your thoughts on using groovy for this?

I had thoughts about moving it over into pure Java8.

Thanks - actually i was too lazy to move it to Java :grin:
But since it is only a small project i was able to do it in groovy.

@StephenOTT @cbuchberger… This plugin takes care of only the REST API’s part. Any idea of how to achieve the same for Webapps?

@pradeep.poojari - please have a look here. This one works for both REST and WebApps

Hi @cbuchberger , I am able to do SSO to camunda webapp if I embed the
authentication ( using spring security with SAML IDP ) with the help ContainerBasedAuthenticationFilter.
…java

@Override
protected void configure(final HttpSecurity http) throws Exception {
	// @formatter:off
	http.csrf().disable();
	http.authorizeRequests().antMatchers("/saml/**").permitAll().anyRequest().authenticated().and().apply(saml())
			.userDetailsService(samlUserService).serviceProvider().protocol(spProtocol).hostname(spHost)
			.basePath(spBashPath).keyStore().storeFilePath(keyStoreFile).keyPassword(keyStorePassword)
			.keyname(keyStoreAlias).and().and().identityProvider().metadataFilePath(metadataPath).and().and();
	// @formatter:on
}

@Bean
public FilterRegistrationBean containerBasedAuthenticationFilter() {
	System.out.println("Inside Spring Filter");
	FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
	filterRegistration.setFilter(new ContainerBasedAuthenticationFilter());
	filterRegistration.setInitParameters(Collections.singletonMap("authentication-provider",
			"com.prad.samldemo.config.SpringSecurityAuthenticationProvider"));
	filterRegistration.setOrder(101); // make sure the filter is registered after the Spring Security Filter Chain
	filterRegistration.addUrlPatterns("/camunda/*");
	return filterRegistration;
}


But When the authentication part developed as a separate service and it provides JWT token. I have challenges in passing this JWT to Camunda webapp ? For REST API we have a control to set JWT in the header either through postman or using javascript client.