This is an automated email from the ASF dual-hosted git repository.

Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git


The following commit(s) were added to refs/heads/main by this push:
     new 90448850a2b CAMEL-24497: camel-undertow-spring-security-starter - 
validate the JWT issuer and audience (#1910)
90448850a2b is described below

commit 90448850a2b73c6d75d089bf0805bbf2e6836e61
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Aug 28 14:05:51 2026 +0200

    CAMEL-24497: camel-undertow-spring-security-starter - validate the JWT 
issuer and audience (#1910)
    
    * CAMEL-24497: camel-undertow-spring-security-starter - validate the JWT 
issuer and audience
    
    jwtDecoderByIssuerUri built the decoder with NimbusJwtDecoder.withJwkSetUri 
and
    installed only a claim-set converter, so the default validator applied: 
signature
    and timestamps were checked, the iss claim was not, and the configured 
clientId
    was used only to build the ClientRegistration - never bound to the token.
    
    Every client of a realm is served by the same signing key, so a token 
minted for
    any other client of that realm satisfied the signature check and was 
accepted.
    
    The decoder now installs JwtValidators.createDefaultWithIssuer for the 
realm the
    client registration already points at, plus an audience validator binding 
the
    token to the configured clientId through its aud or azp claim.
    
    The audience check can be turned off with
    camel.security.undertow.keycloak.validate-audience=false for deployments 
that
    rely on tokens minted for a different client.
    
    Adds the first tests to this starter, which had no test module.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
    Signed-off-by: Andrea Cosentino <[email protected]>
    
    * CAMEL-24497: Require the configured JWT audience
    
    ---------
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
    Co-authored-by: Croway <[email protected]>
---
 .../camel-undertow-spring-security-starter/pom.xml |  7 ++
 .../src/main/doc/intro.adoc                        | 18 +++++
 .../src/main/docs/undertow-spring-security.json    |  7 ++
 .../undertow/spring/boot/JwtAudienceValidator.java | 53 ++++++++++++++
 .../boot/UndertowSpringSecurityCustomizer.java     | 22 ++++++
 .../providers/AbstractProviderConfiguration.java   | 19 +++++
 .../providers/KeycloakProviderConfiguration.java   | 11 ++-
 .../spring/boot/JwtAudienceValidatorTest.java      | 85 ++++++++++++++++++++++
 .../spring/boot/KeycloakIssuerUriTest.java         | 64 ++++++++++++++++
 .../pages/starters/undertow-spring-security.adoc   | 21 +++++-
 10 files changed, 305 insertions(+), 2 deletions(-)

diff --git a/components-starter/camel-undertow-spring-security-starter/pom.xml 
b/components-starter/camel-undertow-spring-security-starter/pom.xml
index bf4c9d40542..c32eb9bb9e7 100644
--- a/components-starter/camel-undertow-spring-security-starter/pom.xml
+++ b/components-starter/camel-undertow-spring-security-starter/pom.xml
@@ -56,6 +56,13 @@
       <artifactId>spring-boot-starter-security</artifactId>
       <version>${spring-boot-version}</version>
     </dependency>
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <version>${spring-boot-version}</version>
+      <scope>test</scope>
+    </dependency>
     <!--START OF GENERATED CODE-->
     <dependency>
       <groupId>org.apache.camel.springboot</groupId>
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/doc/intro.adoc
 
b/components-starter/camel-undertow-spring-security-starter/src/main/doc/intro.adoc
index e748d4b2ae0..a9046a2d389 100644
--- 
a/components-starter/camel-undertow-spring-security-starter/src/main/doc/intro.adoc
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/doc/intro.adoc
@@ -1,3 +1,21 @@
 Spring Boot auto-configuration for Camel Undertow with Spring Security.
 
 This starter secures Camel HTTP endpoints served by the Undertow component 
using Spring Security. It supports OAuth2/OpenID Connect providers (such as 
Keycloak) for authentication and authorization of incoming HTTP requests to 
Camel routes.
+
+== Token validation
+
+Incoming JWTs are validated against the configured provider on three points: 
the standard timestamp checks,
+the `iss` claim (which must match the configured realm), and the audience — 
the token must carry the
+configured `clientId` in its `aud` claim. Keycloak may require an Audience 
protocol mapper to add the service
+client to access tokens.
+
+The audience check matters because every client of a realm is served by the 
same signing key. Without it, a
+token minted for any other client in the realm — including a low-trust public 
one — satisfies the signature
+check and is accepted here.
+
+It can be turned off if an existing deployment relies on tokens minted for a 
different client:
+
+[source,properties]
+----
+camel.security.undertow.keycloak.validate-audience = false
+----
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/docs/undertow-spring-security.json
 
b/components-starter/camel-undertow-spring-security-starter/src/main/docs/undertow-spring-security.json
index f012f2dfab8..304c56c315b 100644
--- 
a/components-starter/camel-undertow-spring-security-starter/src/main/docs/undertow-spring-security.json
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/docs/undertow-spring-security.json
@@ -43,6 +43,13 @@
       "description": "Name of the attribute, which will be used as username.",
       "sourceType": 
"org.apache.camel.undertow.spring.boot.providers.KeycloakProviderConfiguration",
       "defaultValue": "preferred_username"
+    },
+    {
+      "name": "camel.security.undertow.keycloak.validate-audience",
+      "type": "java.lang.Boolean",
+      "description": "Whether an incoming token must carry the configured 
client id in its aud claim. Every client of a realm shares the signing key, so 
with this disabled a token minted for any other client of the same realm is 
accepted.",
+      "sourceType": 
"org.apache.camel.undertow.spring.boot.providers.KeycloakProviderConfiguration",
+      "defaultValue": true
     }
   ],
   "hints": [],
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidator.java
 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidator.java
new file mode 100644
index 00000000000..d87a285361e
--- /dev/null
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidator.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.undertow.spring.boot;
+
+import org.springframework.security.oauth2.core.OAuth2Error;
+import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
+import org.springframework.security.oauth2.core.OAuth2TokenValidator;
+import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
+import org.springframework.security.oauth2.jwt.Jwt;
+
+import java.util.List;
+
+/**
+ * Checks that a JWT was actually issued for the configured client.
+ * <p/>
+ * A signature check alone only proves the token came from the realm; every 
client of that realm shares it. Without
+ * this validator a token minted for any other client in the same realm is 
accepted here, so the token is bound to the
+ * configured client id through the {@code aud} claim.
+ */
+class JwtAudienceValidator implements OAuth2TokenValidator<Jwt> {
+
+    private final String clientId;
+
+    JwtAudienceValidator(String clientId) {
+        this.clientId = clientId;
+    }
+
+    @Override
+    public OAuth2TokenValidatorResult validate(Jwt token) {
+        final List<String> audience = token.getAudience();
+        if (audience != null && audience.contains(clientId)) {
+            return OAuth2TokenValidatorResult.success();
+        }
+        return OAuth2TokenValidatorResult.failure(new OAuth2Error(
+                OAuth2ErrorCodes.INVALID_TOKEN,
+                "The token audience does not contain the configured client id: 
'" + clientId + "'",
+                "https://datatracker.ietf.org/doc/html/rfc9068#section-4";));
+    }
+}
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/UndertowSpringSecurityCustomizer.java
 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/UndertowSpringSecurityCustomizer.java
index 19d42874344..7320061ba6e 100644
--- 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/UndertowSpringSecurityCustomizer.java
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/UndertowSpringSecurityCustomizer.java
@@ -42,7 +42,11 @@ import 
org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
 import 
org.springframework.security.oauth2.client.registration.ClientRegistration;
 import 
org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import 
org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
+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.JwtValidators;
 import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
 import org.springframework.security.web.SecurityFilterChain;
 
@@ -106,9 +110,27 @@ public class UndertowSpringSecurityCustomizer implements 
ComponentCustomizer {
         final String jwkSetUri = 
getClientRegistration().getProviderDetails().getJwkSetUri();
         final NimbusJwtDecoder jwtDecoder = 
NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
         jwtDecoder.setClaimSetConverter(new 
KeycloakUsernameSubClaimAdapter(getProvider().getUserNameAttribute()));
+        // building the decoder from the JWK set URI pins the signing keys but 
installs no claim validation beyond
+        // timestamps, so bind the token to the configured issuer and client 
explicitly
+        jwtDecoder.setJwtValidator(jwtValidator());
         return jwtDecoder;
     }
 
+    private OAuth2TokenValidator<Jwt> jwtValidator() {
+        final String issuerUri;
+        try {
+            issuerUri = getProvider().getIssuerUri();
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException("Provider url is not correct.", 
e);
+        }
+        final OAuth2TokenValidator<Jwt> withIssuer = 
JwtValidators.createDefaultWithIssuer(issuerUri);
+        if (!getProvider().isValidateAudience()) {
+            return withIssuer;
+        }
+        return new DelegatingOAuth2TokenValidator<>(withIssuer,
+                new 
JwtAudienceValidator(getClientRegistration().getClientId()));
+    }
+
     @Bean
     public ClientRegistrationRepository clientRegistrationRepository() {
         return new 
InMemoryClientRegistrationRepository(Collections.singletonList(getClientRegistration()));
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/AbstractProviderConfiguration.java
 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/AbstractProviderConfiguration.java
index 468e95b4247..dcc4e6526dc 100644
--- 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/AbstractProviderConfiguration.java
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/AbstractProviderConfiguration.java
@@ -32,12 +32,31 @@ public abstract class AbstractProviderConfiguration {
         keycloak
     }
 
+    /**
+     * Whether an incoming token must carry the configured client id in its 
aud claim. Every client of a realm shares
+     * the signing key, so with this disabled a token minted for any other 
client of the same realm is accepted.
+     */
+    private boolean validateAudience = true;
+
     abstract TYPE getType();
 
     public abstract ClientRegistration getClientRegistration() throws 
URISyntaxException;
 
     public abstract String getUserNameAttribute();
 
+    /**
+     * The issuer the provider stamps into the {@code iss} claim of the tokens 
it mints.
+     */
+    public abstract String getIssuerUri() throws URISyntaxException;
+
+    public boolean isValidateAudience() {
+        return validateAudience;
+    }
+
+    public void setValidateAudience(boolean validateAudience) {
+        this.validateAudience = validateAudience;
+    }
+
     public Converter<Jwt, ? extends AbstractAuthenticationToken> 
getJwtAuthenticationConverter() {
         throw new IllegalArgumentException("Not implemented");
     }
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/KeycloakProviderConfiguration.java
 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/KeycloakProviderConfiguration.java
index 37a322066f2..49e84b33b9a 100644
--- 
a/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/KeycloakProviderConfiguration.java
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/main/java/org/apache/camel/undertow/spring/boot/providers/KeycloakProviderConfiguration.java
@@ -60,9 +60,18 @@ public class KeycloakProviderConfiguration extends 
AbstractProviderConfiguration
         return new KeycloakJwtAuthenticationConverter();
     }
 
+    @Override
+    public String getIssuerUri() throws URISyntaxException {
+        return realmUri().toString();
+    }
+
+    private URI realmUri() throws URISyntaxException {
+        return new URI(getUrl()).resolve("/auth/realms/" + getRealmId());
+    }
+
     @Override
     public ClientRegistration getClientRegistration() throws 
URISyntaxException {
-        URI keycloakUri = new URI(getUrl()).resolve("/auth/realms/" + 
getRealmId() + "/protocol/openid-connect");
+        URI keycloakUri = URI.create(realmUri() + "/protocol/openid-connect");
         return 
ClientRegistration.withRegistrationId(getType().name()).clientId(getClientId())
                 
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                 
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}").scope("openid", 
"profile", "email")
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidatorTest.java
 
b/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidatorTest.java
new file mode 100644
index 00000000000..1f09c62051c
--- /dev/null
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/JwtAudienceValidatorTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.undertow.spring.boot;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
+import org.springframework.security.oauth2.jwt.Jwt;
+
+import java.time.Instant;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * A token signed by the realm is not automatically a token meant for this 
client: every client of the realm shares the
+ * signing key, so the audience has to be checked explicitly.
+ */
+public class JwtAudienceValidatorTest {
+
+    private static final String CLIENT_ID = "camel-client";
+
+    private final JwtAudienceValidator validator = new 
JwtAudienceValidator(CLIENT_ID);
+
+    private static Jwt token(List<String> audience, String authorizedParty) {
+        Jwt.Builder builder = Jwt.withTokenValue("token")
+                .header("alg", "RS256")
+                .issuedAt(Instant.now())
+                .expiresAt(Instant.now().plusSeconds(300))
+                .claim("sub", "someone");
+        if (audience != null) {
+            builder.audience(audience);
+        }
+        if (authorizedParty != null) {
+            builder.claim("azp", authorizedParty);
+        }
+        return builder.build();
+    }
+
+    @Test
+    public void acceptsTokenWithThisClientInAudience() {
+        OAuth2TokenValidatorResult result = 
validator.validate(token(List.of(CLIENT_ID), null));
+        assertFalse(result.hasErrors(), "a token addressed to this client 
should be accepted");
+    }
+
+    @Test
+    public void 
rejectsMatchingAuthorizedPartyWhenAudienceTargetsAnotherService() {
+        OAuth2TokenValidatorResult result = 
validator.validate(token(List.of("account"), CLIENT_ID));
+        assertTrue(result.hasErrors(), "the authorized party must not override 
a mismatching audience");
+    }
+
+    @Test
+    public void rejectsTokenMintedForAnotherClientInTheSameRealm() {
+        OAuth2TokenValidatorResult result = 
validator.validate(token(List.of("other-spa"), "other-spa"));
+        assertTrue(result.hasErrors(), "a token issued to a different client 
of the same realm must be rejected");
+        
assertTrue(result.getErrors().iterator().next().getDescription().contains(CLIENT_ID),
+                "the failure should name the expected client id");
+    }
+
+    @Test
+    public void rejectsTokenCarryingNoAudience() {
+        OAuth2TokenValidatorResult result = validator.validate(token(null, 
null));
+        assertTrue(result.hasErrors(), "a token without an audience must be 
rejected");
+    }
+
+    @Test
+    public void acceptsWhenThisClientIsOneOfSeveralAudiences() {
+        OAuth2TokenValidatorResult result = 
validator.validate(token(List.of("account", CLIENT_ID), "gateway"));
+        assertFalse(result.hasErrors(), "aud may legitimately carry several 
entries");
+    }
+}
diff --git 
a/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/KeycloakIssuerUriTest.java
 
b/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/KeycloakIssuerUriTest.java
new file mode 100644
index 00000000000..9ca1c225ffe
--- /dev/null
+++ 
b/components-starter/camel-undertow-spring-security-starter/src/test/java/org/apache/camel/undertow/spring/boot/KeycloakIssuerUriTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.undertow.spring.boot;
+
+import 
org.apache.camel.undertow.spring.boot.providers.KeycloakProviderConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The issuer used to validate the {@code iss} claim must be the realm the 
client registration already points at,
+ * otherwise every token would be rejected.
+ */
+public class KeycloakIssuerUriTest {
+
+    private static KeycloakProviderConfiguration provider(String url) {
+        KeycloakProviderConfiguration provider = new 
KeycloakProviderConfiguration();
+        provider.setUrl(url);
+        provider.setRealmId("my-realm");
+        provider.setClientId("camel-client");
+        return provider;
+    }
+
+    @Test
+    public void derivesTheRealmIssuer() throws Exception {
+        assertEquals("http://localhost:8080/auth/realms/my-realm";, 
provider("http://localhost:8080";).getIssuerUri());
+    }
+
+    @Test
+    public void ignoresAnyPathOnTheConfiguredUrl() throws Exception {
+        // the client registration resolves from the root too, so both must 
agree
+        assertEquals("https://sso.example.com/auth/realms/my-realm";,
+                provider("https://sso.example.com/some/path";).getIssuerUri());
+    }
+
+    @Test
+    public void issuerIsThePrefixOfTheJwkSetUri() throws Exception {
+        KeycloakProviderConfiguration provider = 
provider("http://localhost:8080";);
+        String jwkSetUri = 
provider.getClientRegistration().getProviderDetails().getJwkSetUri();
+        assertTrue(jwkSetUri.startsWith(provider.getIssuerUri()),
+                "issuer " + provider.getIssuerUri() + " should prefix the jwk 
set uri " + jwkSetUri);
+        
assertEquals("http://localhost:8080/auth/realms/my-realm/protocol/openid-connect/certs";,
 jwkSetUri);
+    }
+
+    @Test
+    public void audienceValidationIsOnByDefault() {
+        assertTrue(provider("http://localhost:8080";).isValidateAudience());
+    }
+}
diff --git 
a/docs/spring-boot/modules/ROOT/pages/starters/undertow-spring-security.adoc 
b/docs/spring-boot/modules/ROOT/pages/starters/undertow-spring-security.adoc
index 8c849fa8171..0303c75c2e3 100644
--- a/docs/spring-boot/modules/ROOT/pages/starters/undertow-spring-security.adoc
+++ b/docs/spring-boot/modules/ROOT/pages/starters/undertow-spring-security.adoc
@@ -7,6 +7,24 @@ Spring Boot auto-configuration for Camel Undertow with Spring 
Security.
 
 This starter secures Camel HTTP endpoints served by the Undertow component 
using Spring Security. It supports OAuth2/OpenID Connect providers (such as 
Keycloak) for authentication and authorization of incoming HTTP requests to 
Camel routes.
 
+== Token validation
+
+Incoming JWTs are validated against the configured provider on three points: 
the standard timestamp checks,
+the `iss` claim (which must match the configured realm), and the audience — 
the token must carry the
+configured `clientId` in its `aud` claim. Keycloak may require an Audience 
protocol mapper to add the service
+client to access tokens.
+
+The audience check matters because every client of a realm is served by the 
same signing key. Without it, a
+token minted for any other client in the realm — including a low-trust public 
one — satisfies the signature
+check and is accepted here.
+
+It can be turned off if an existing deployment relies on tokens minted for a 
different client:
+
+[source,properties]
+----
+camel.security.undertow.keycloak.validate-audience = false
+----
+
 == Maven coordinates
 
 [source,xml]
@@ -19,7 +37,7 @@ This starter secures Camel HTTP endpoints served by the 
Undertow component using
 
 == Spring Boot Auto-Configuration
 
-The starter supports 5 options, which are listed below.
+The starter supports 6 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -29,4 +47,5 @@ The starter supports 5 options, which are listed below.
 | camel.security.undertow.keycloak.realm-id | Realm id from the keycloak 
server used for authentication. |  | String
 | camel.security.undertow.keycloak.url | Url to keycloak server which will be 
used in spring security configuration. (Example "http://localhost:8080";) |  | 
String
 | camel.security.undertow.keycloak.user-name-attribute | Name of the 
attribute, which will be used as username. | preferred_username | String
+| camel.security.undertow.keycloak.validate-audience | Whether an incoming 
token must carry the configured client id in its aud claim. Every client of a 
realm shares the signing key, so with this disabled a token minted for any 
other client of the same realm is accepted. | true | Boolean
 |===

Reply via email to