Skip to content

Commit

Permalink
Merge pull request #122 from cachescrubber/gh-121
Browse files Browse the repository at this point in the history
Support Spring Boot 3.x / Camunda 7.20
  • Loading branch information
VonDerBeck authored Aug 18, 2023
2 parents d36aead + 4d49080 commit 0f97de5
Show file tree
Hide file tree
Showing 33 changed files with 2,228 additions and 250 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Java setup
uses: actions/setup-java@e54a62b3df9364d4b4c1c29c7225e57fe605d7dd # pin@v1
with:
java-version: 1.8
java-version: 17
- name: Cache
uses: actions/cache@0781355a23dac32fd3bac414512f4b903437991a # pin@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Set up Java environment
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 17
gpg-private-key: ${{ secrets.MAVEN_CENTRAL_GPG_SIGNING_KEY_SEC }}
gpg-passphrase: MAVEN_CENTRAL_GPG_PASSPHRASE
- name: Deploy SNAPSHOT / Release
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
/extension-run/dependency-reduced-pom.xml
/examples/sso-kubernetes/camunda-db.mv.db
/camunda-db.mv.db
/.run/camunda-platform-7-keycloak-root [clean,install].run.xml
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ This plugin provides the basis for using Keycloak as Identity Management solutio
**Beware: in case you want to use Keycloak's advanced login capabilities for social connections you must configure SSO as well.**
Password grant exchanges are only supported for Keycloak's internally managed users and users of an LDAP / Keberos User federation. Hence without SSO you will only be able to login with users managed by such connections.

Current version: `7.19.0`<br >
Latest tests with: Keycloak `21.1.1`, `19.0.3-legacy`, Camunda `7.19.0`, `7.19.0-ee`
Current version: `7.20.0-SNAPSHOT`<br >
Latest tests with: Keycloak `21.1.1`, `19.0.3-legacy`, Camunda `7.20.0-alpha3`

#### Features
Changes in version `7.20.0`

With 7.20.0 Camunda Platform 7 will switch to Spring Boot 3.1, JakartaEE 10 and a JDK 17 baseline. The Keycloak Identity Provider Plugin has been updated to support the new baseline versions of it's major dependencies.

* Upgrade to Camunda Platform 7.20.0
* Upgrade to Spring Boot 3.1.x
* Upgrade to Apache HttpComponents HttpClient 5
* Updated samples to Spring Security 6.1

Changes in version `7.19.0`

Expand Down
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: "3.9"

services:
jboss.keycloak:
image: quay.io/keycloak/keycloak:21.1.1
restart: always
environment:
TZ: Europe/Berlin
DB_VENDOR: h2
KEYCLOAK_ADMIN: keycloak
KEYCLOAK_ADMIN_PASSWORD: keycloak1!
KC_HTTP_RELATIVE_PATH: /auth
ports:
- "8443:8443"
- "8080:8080"
command:
- start-dev
- --features admin-fine-grained-authz
19 changes: 3 additions & 16 deletions examples/jwt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.camunda.bpm.extension.examples</groupId>
<artifactId>camunda-platform-7-keycloak-examples</artifactId>
<version>7.19.1-SNAPSHOT</version>
<version>7.20.0-SNAPSHOT</version>
</parent>

<artifactId>camunda-platform-7-keycloak-examples-jwt</artifactId>
Expand All @@ -17,18 +17,6 @@
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<dependencyManagement>
<dependencies>
<!-- temporarily fix deserialisation bug when parsing nested objects
of Keycloak answer inside Spring Security init -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.12</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
Expand Down Expand Up @@ -75,10 +63,9 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Required to run with Java 11 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>

<!-- Test dependencies -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.camunda.bpm.extension.keycloak.showcase.sso;

import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;

import org.camunda.bpm.extension.keycloak.auth.KeycloakJwtAuthenticationFilter;
import org.camunda.bpm.extension.keycloak.config.KeycloakCockpitConfiguration;
import org.camunda.bpm.extension.keycloak.config.KeycloakConfigurationFilterRegistrationBean;
Expand All @@ -10,20 +12,22 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.context.request.RequestContextListener;

import javax.inject.Inject;
import jakarta.inject.Inject;
import java.util.Collections;

/**
* Camunda Web application SSO configuration for usage with KeycloakIdentityProviderPlugin.
*/
@ConditionalOnMissingClass("org.springframework.test.context.junit.jupiter.SpringExtension")
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
@EnableWebSecurity
public class WebAppSecurityConfig {

private static final int AFTER_SPRING_SECURITY_FILTER_CHAIN_ORDER = 201;
private static final String API_FILTER_PATTERN = "/api/*";
Expand All @@ -35,22 +39,23 @@ public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
@Inject
private KeycloakCockpitConfiguration keycloakCockpitConfiguration;

@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain httpSecurity(HttpSecurity http) throws Exception {
String path = camundaBpmProperties.getWebapp().getApplicationPath();
http
.csrf().ignoringAntMatchers("/api/**", "/engine-rest/**")
.and()
.requestMatchers().antMatchers("/**").and()
.authorizeRequests(authz -> authz
.antMatchers( "/").permitAll()
.antMatchers(path + "/app/**").permitAll()
.antMatchers(path + "/lib/**").permitAll()
.antMatchers(path + "/api/engine/engine/**").permitAll()
.antMatchers(path + "/api/*/plugin/*/static/app/plugin.css").permitAll()
.antMatchers(path + "/api/*/plugin/*/static/app/plugin.js").permitAll()
return http
.csrf(csrf -> csrf
.ignoringRequestMatchers(antMatcher("/api/**"), antMatcher("/engine-rest/**")))
.authorizeHttpRequests(authz -> authz
.requestMatchers(antMatcher("/")).permitAll()
.requestMatchers(antMatcher(path + "/app/**")).permitAll()
.requestMatchers(antMatcher(path + "/assets/**")).permitAll()
.requestMatchers(antMatcher(path + "/lib/**")).permitAll()
.requestMatchers(antMatcher(path + "/api/engine/engine/**")).permitAll()
.requestMatchers(antMatcher(path + "/api/*/plugin/*/static/app/plugin.css")).permitAll()
.requestMatchers(antMatcher(path + "/api/*/plugin/*/static/app/plugin.js")).permitAll()
.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2.jwt());
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.build();
}

@SuppressWarnings({ "rawtypes", "unchecked" })
Expand Down
2 changes: 1 addition & 1 deletion examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.camunda.bpm.extension</groupId>
<artifactId>camunda-platform-7-keycloak-root</artifactId>
<version>7.19.1-SNAPSHOT</version>
<version>7.20.0-SNAPSHOT</version>
</parent>

<groupId>org.camunda.bpm.extension.examples</groupId>
Expand Down
60 changes: 29 additions & 31 deletions examples/sso-kubernetes/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.camunda.bpm.extension.examples</groupId>
<artifactId>camunda-platform-7-keycloak-examples</artifactId>
<version>7.19.1-SNAPSHOT</version>
<version>7.20.0-SNAPSHOT</version>
</parent>

<artifactId>camunda-platform-7-keycloak-examples-sso-kubernetes</artifactId>
Expand All @@ -17,23 +17,11 @@
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<dependencyManagement>
<dependencies>
<!-- temporarily fix deserialisation bug when parsing nested objects
of Keycloak answer inside Spring Security init -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.12</version>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<!-- <artifactId>camunda-bpm-spring-boot-starter-webapp-ee</artifactId> -->
<!-- <artifactId>camunda-bpm-spring-boot-starter-webapp-ee</artifactId> -->
</dependency>

<dependency>
Expand All @@ -46,29 +34,29 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

<!-- Keycloak Identity Prover Plugin -->
<dependency>
<groupId>org.camunda.bpm.extension</groupId>
<artifactId>camunda-platform-7-keycloak</artifactId>
<groupId>org.camunda.bpm.extension</groupId>
<artifactId>camunda-platform-7-keycloak</artifactId>
</dependency>

<!-- Database -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

<dependency>
Expand All @@ -92,10 +80,9 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Required to run with Java 11 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>

<!-- Test dependencies -->
Expand Down Expand Up @@ -125,6 +112,17 @@

<!-- Add your own dependencies here, if in compile scope, they are added
to the jar -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.dasniko</groupId>
<artifactId>testcontainers-keycloak</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;

import org.camunda.bpm.engine.IdentityService;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
package org.camunda.bpm.extension.keycloak.showcase.rest;

import javax.inject.Inject;

import jakarta.inject.Inject;
import org.camunda.bpm.engine.IdentityService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.*;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;

/**
* Optional Security Configuration for Camunda REST Api.
*/
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.BASIC_AUTH_ORDER - 20)
@ConditionalOnProperty(name = "rest.security.enabled", havingValue = "true", matchIfMissing = true)
public class RestApiSecurityConfig extends WebSecurityConfigurerAdapter {
public class RestApiSecurityConfig {

/** Configuration for REST Api security. */
@Inject
Expand All @@ -49,21 +42,23 @@ public class RestApiSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* {@inheritDoc}
*/
@Override
public void configure(final HttpSecurity http) throws Exception {
@Bean
@Order(2)
public SecurityFilterChain httpSecurityRest(HttpSecurity http, JwtDecoder jwtDecoder) throws Exception {
String jwkSetUri = applicationContext.getEnvironment().getRequiredProperty(
"spring.security.oauth2.client.provider." + configProps.getProvider() + ".jwk-set-uri");

http
.csrf().ignoringAntMatchers("/api/**", "/engine-rest/**")
.and()
.antMatcher("/engine-rest/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt().jwkSetUri(jwkSetUri)
;
return http
.csrf(csrf -> csrf
.ignoringRequestMatchers(antMatcher("/api/**"), antMatcher("/engine-rest/**")))
.authorizeHttpRequests(authorize -> authorize.
requestMatchers(antMatcher("/engine-rest/**")).authenticated()
.anyRequest().authenticated())
.oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer
.jwt(jwt -> jwt
.decoder(jwtDecoder)
.jwkSetUri(jwkSetUri)))
.build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.camunda.bpm.extension.keycloak.showcase.rest;

import javax.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotEmpty;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
Expand Down
Loading

0 comments on commit 0f97de5

Please sign in to comment.