This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 39133b1ada37 CAMEL-23504: camel-keycloak - include IS_ACTIVE check in
parseAndVerifyAccessToken (#23197)
39133b1ada37 is described below
commit 39133b1ada37c60dea53f3b7db720dbd2ae73fa6
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu May 14 09:19:03 2026 +0200
CAMEL-23504: camel-keycloak - include IS_ACTIVE check in
parseAndVerifyAccessToken (#23197)
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 c3ec59574f04..fa8408d05bbf 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
@@ -63,6 +63,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 34e6041de9ac..92d31b94f260 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
@@ -26,6 +26,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;
@@ -176,6 +177,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);