This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-26902-keycloak-26.8.2 in repository https://gitbox.apache.org/repos/asf/camel.git
commit f04b1cc858c7d4d4ccf3dd70e0cdd212d5c1e4c1 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Nov 12 22:50:41 2026 +0100 CAMEL-26902: camel-keycloak - upgrade test container to Keycloak 26.8.2 and grant kc-admin-api to the admin client Keycloak 26.8.2 enforces an audience check on the Admin REST API: a token must carry the new built-in kc-admin-api client scope, which the upgrade assigns only to admin-cli and security-admin-console. The client that KeycloakProducerRevocationIT creates for the client-credentials producer did not have it, so logoutAllUsers and pushNotBefore failed with 401. - test-infra: Keycloak container 26.8.1 -> 26.8.2 - KeycloakProducerRevocationIT assigns kc-admin-api to its client when the scope exists (older Keycloak versions have no such scope) - keycloak-producer.adoc and the 4.24 upgrade guide: clients used with clientId/clientSecret, or a pre-obtained accessToken, need the scope on Keycloak 26.8.2+ Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../org/apache/camel/catalog/docs/keycloak-producer.adoc | 6 ++++++ .../org/apache/camel/catalog/test-infra/metadata.json | 2 +- .../camel-keycloak/src/main/docs/keycloak-producer.adoc | 6 ++++++ .../component/keycloak/KeycloakProducerRevocationIT.java | 16 ++++++++++++++-- .../modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 9 +++++++++ .../src/generated/resources/META-INF/metadata.json | 2 +- .../test/infra/keycloak/services/container.properties | 2 +- 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-producer.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-producer.adoc index 24f6065c9e0a..a0778eb6a792 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-producer.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-producer.adoc @@ -101,6 +101,12 @@ keycloak.setConfiguration(config); ---- ==== +NOTE: From Keycloak 26.8.2 the Admin REST API accepts only access tokens that carry the built-in `kc-admin-api` client +scope. Keycloak assigns that scope to its own `admin-cli` and `security-admin-console` clients, which username/password +authentication uses, but not to your own clients. Assign `kc-admin-api` (as a default client scope) to the client +used for client credentials, otherwise the operations fail with `401 Unauthorized`. A pre-obtained access token +(`accessToken`) must be issued with that scope too. + == Supported Operations The component supports the following operations: diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json index 4e20c62fb386..51503f728729 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json @@ -106,7 +106,7 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-keycloak", "version" : "4.24.0-SNAPSHOT", - "serviceVersion" : "26.8.1", + "serviceVersion" : "26.8.2", "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.azure.key.vault.services.AzureKeyVaultInfraService", diff --git a/components/camel-keycloak/src/main/docs/keycloak-producer.adoc b/components/camel-keycloak/src/main/docs/keycloak-producer.adoc index 24f6065c9e0a..a0778eb6a792 100644 --- a/components/camel-keycloak/src/main/docs/keycloak-producer.adoc +++ b/components/camel-keycloak/src/main/docs/keycloak-producer.adoc @@ -101,6 +101,12 @@ keycloak.setConfiguration(config); ---- ==== +NOTE: From Keycloak 26.8.2 the Admin REST API accepts only access tokens that carry the built-in `kc-admin-api` client +scope. Keycloak assigns that scope to its own `admin-cli` and `security-admin-console` clients, which username/password +authentication uses, but not to your own clients. Assign `kc-admin-api` (as a default client scope) to the client +used for client credentials, otherwise the operations fail with `401 Unauthorized`. A pre-obtained access token +(`accessToken`) must be issued with that scope too. + == Supported Operations The component supports the following operations: diff --git a/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/KeycloakProducerRevocationIT.java b/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/KeycloakProducerRevocationIT.java index 15af200d1583..8584eff95980 100644 --- a/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/KeycloakProducerRevocationIT.java +++ b/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/KeycloakProducerRevocationIT.java @@ -17,6 +17,7 @@ package org.apache.camel.component.keycloak; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -69,6 +70,8 @@ public class KeycloakProducerRevocationIT extends CamelTestSupport { private static final String TEST_USER = "test-user-" + UUID.randomUUID().toString().substring(0, 8); private static final String TEST_PASSWORD = "password123"; + private static final String ADMIN_API_CLIENT_SCOPE = "kc-admin-api"; + private static Keycloak keycloakAdminClient; private static RealmResource realmResource; @@ -126,7 +129,16 @@ public class KeycloakProducerRevocationIT extends CamelTestSupport { realmResource.users().get(serviceAccount.getId()).roles().clientLevel(realmManagementId) .add(realmResource.clients().get(realmManagementId).roles().list().stream() .filter(r -> r.getName().equals("manage-realm") || r.getName().equals("manage-users")) - .collect(java.util.stream.Collectors.toList())); + .toList()); + + // From Keycloak 26.8.2 the Admin REST API only accepts tokens with the built-in kc-admin-api scope + // (it adds the Admin API audience), and the upgrade assigns it to admin-cli and security-admin-console + // only. The producer calls the Admin API with a token of this client, so the client needs the scope. + // Older Keycloak versions do not have the scope and accept the token without it. + realmResource.clientScopes().findAll().stream() + .filter(scope -> ADMIN_API_CLIENT_SCOPE.equals(scope.getName())) + .findFirst() + .ifPresent(scope -> clientResource.addDefaultClientScope(scope.getId())); } // Create user UserRepresentation user = new UserRepresentation(); @@ -136,7 +148,7 @@ public class KeycloakProducerRevocationIT extends CamelTestSupport { user.setEmail(TEST_USER + "@test.com"); user.setEnabled(true); user.setEmailVerified(true); - user.setRequiredActions(java.util.Collections.emptyList()); + user.setRequiredActions(Collections.emptyList()); CredentialRepresentation cred = new CredentialRepresentation(); cred.setType(CredentialRepresentation.PASSWORD); cred.setValue(TEST_PASSWORD); diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc index 949c547b870c..31ec30a3f996 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc @@ -302,6 +302,15 @@ The camel-sjms and camel-sjms2 consumers now map a received `jakarta.jms.StreamM bytes, as the camel-jms consumer does, so a body sent with `jmsMessageType=Stream` arrives as the bytes that were sent. Before, the body was the `jakarta.jms.StreamMessage` itself. To get the JMS message, use `mapJmsMessage=false`. +=== camel-keycloak - Keycloak 26.8.2 requires the kc-admin-api client scope + +This is a change in Keycloak, not in Camel: from Keycloak 26.8.2 the Admin REST API accepts only access tokens that +carry the built-in `kc-admin-api` client scope, and rejects other tokens with `401 Unauthorized`. The Keycloak upgrade +assigns the scope to `admin-cli` and `security-admin-console` only. When the `keycloak` producer authenticates with +`clientId` and `clientSecret` of your own client, assign `kc-admin-api` to that client as a default client scope; a +pre-obtained `accessToken` must be issued with that scope too. Username and password authentication uses `admin-cli` +and keeps working. The integration tests of camel-keycloak now run against Keycloak 26.8.2. + === Java *Breaking change:* Camel 4.24 requires *Java 21* as the minimum runtime version. diff --git a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json index 4e20c62fb386..51503f728729 100644 --- a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json +++ b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json @@ -106,7 +106,7 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-keycloak", "version" : "4.24.0-SNAPSHOT", - "serviceVersion" : "26.8.1", + "serviceVersion" : "26.8.2", "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.azure.key.vault.services.AzureKeyVaultInfraService", diff --git a/test-infra/camel-test-infra-keycloak/src/main/resources/org/apache/camel/test/infra/keycloak/services/container.properties b/test-infra/camel-test-infra-keycloak/src/main/resources/org/apache/camel/test/infra/keycloak/services/container.properties index 881e4cc56f8d..6219c78f6075 100644 --- a/test-infra/camel-test-infra-keycloak/src/main/resources/org/apache/camel/test/infra/keycloak/services/container.properties +++ b/test-infra/camel-test-infra-keycloak/src/main/resources/org/apache/camel/test/infra/keycloak/services/container.properties @@ -15,6 +15,6 @@ ## limitations under the License. ## --------------------------------------------------------------------------- ## Keycloak container configuration for test-infra -keycloak.container=mirror.gcr.io/keycloak/keycloak:26.8.1 +keycloak.container=mirror.gcr.io/keycloak/keycloak:26.8.2 keycloak.container.ppc64le=icr.io/ppc64le-oss/keycloak-ppc64le:v26.0.5-bv keycloak.container.version.exclude=nightly
