This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.18.x by this push:
new 7f4c4736021a CAMEL-23504: camel-keycloak - include IS_ACTIVE check in
parseAndVerifyAccessToken (#23204)
7f4c4736021a is described below
commit 7f4c4736021aff4fad925eca3bf456b95db038f3
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu May 14 10:09:31 2026 +0200
CAMEL-23504: camel-keycloak - include IS_ACTIVE check in
parseAndVerifyAccessToken (#23204)
KeycloakSecurityHelper.parseAndVerifyAccessToken built its TokenVerifier
with only SUBJECT_EXISTS_CHECK and a RealmUrlCheck. The Keycloak
TokenVerifier starts with an empty internal check list and withChecks(...)
appends rather than replacing a default set, so the built-in IS_ACTIVE
predicate (which validates the exp and nbf claims) was not part of the
verification chain.
Add IS_ACTIVE to the withChecks(...) invocation so the helper enforces
the token's validity window in addition to signature, subject and issuer.
Two unit tests are added in KeycloakSecurityHelperTest:
* testParseAndVerifyAccessTokenRejectsExpiredToken signs a token whose
exp claim is in the past and asserts that parseAndVerifyAccessToken
throws VerificationException.
* testParseAndVerifyAccessTokenAcceptsValidToken signs an unexpired
token and asserts that verification returns the parsed claims.
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../keycloak/security/KeycloakSecurityHelper.java | 1 +
.../security/KeycloakSecurityHelperTest.java | 47 ++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git
a/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelper.java
b/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelper.java
index 30967fbeed7c..24dcacf7835c 100644
---
a/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelper.java
+++
b/components/camel-keycloak/src/main/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelper.java
@@ -62,6 +62,7 @@ public final class KeycloakSecurityHelper {
.publicKey(publicKey)
.withChecks(
TokenVerifier.SUBJECT_EXISTS_CHECK,
+ TokenVerifier.IS_ACTIVE,
new TokenVerifier.RealmUrlCheck(expectedIssuer));
AccessToken token = verifier.verify().getToken();
diff --git
a/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelperTest.java
b/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelperTest.java
index 2cbdc9ae61ba..12798ed17837 100644
---
a/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelperTest.java
+++
b/components/camel-keycloak/src/test/java/org/apache/camel/component/keycloak/security/KeycloakSecurityHelperTest.java
@@ -23,6 +23,7 @@ import java.util.Set;
import org.junit.jupiter.api.Test;
import org.keycloak.common.VerificationException;
+import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.representations.AccessToken;
import org.mockito.Mockito;
@@ -173,6 +174,52 @@ public class KeycloakSecurityHelperTest {
});
}
+ @Test
+ void testParseAndVerifyAccessTokenRejectsExpiredToken() throws Exception {
+ String expectedIssuer = "http://localhost:8080/realms/test";
+
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(2048);
+ KeyPair keyPair = keyGen.generateKeyPair();
+
+ AccessToken token = new AccessToken();
+ token.issuer(expectedIssuer);
+ token.subject("user-123");
+ token.exp(System.currentTimeMillis() / 1000 - 3600);
+
+ String signed = new JWSBuilder()
+ .type("JWT")
+ .jsonContent(token)
+ .rsa256(keyPair.getPrivate());
+
+ assertThrows(VerificationException.class,
+ () -> KeycloakSecurityHelper.parseAndVerifyAccessToken(signed,
keyPair.getPublic(), expectedIssuer));
+ }
+
+ @Test
+ void testParseAndVerifyAccessTokenAcceptsValidToken() throws Exception {
+ String expectedIssuer = "http://localhost:8080/realms/test";
+
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(2048);
+ KeyPair keyPair = keyGen.generateKeyPair();
+
+ AccessToken token = new AccessToken();
+ token.issuer(expectedIssuer);
+ token.subject("user-123");
+ token.exp(System.currentTimeMillis() / 1000 + 3600);
+
+ String signed = new JWSBuilder()
+ .type("JWT")
+ .jsonContent(token)
+ .rsa256(keyPair.getPrivate());
+
+ AccessToken verified
+ = KeycloakSecurityHelper.parseAndVerifyAccessToken(signed,
keyPair.getPublic(), expectedIssuer);
+ assertEquals("user-123", verified.getSubject());
+ assertEquals(expectedIssuer, verified.getIssuer());
+ }
+
@Test
void testExtractPermissions() {
AccessToken token = Mockito.mock(AccessToken.class);