This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch 4.1.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 0fab94e3d2bbdcdfb5d7baea5fad13b008090dfd Author: Naveed Khan <[email protected]> AuthorDate: Wed Oct 28 15:45:46 2026 +0530 validate claims on jwe-only tokens in JoseJwtConsumer (#3639) (cherry picked from commit d4335d43189fa278f7645dbee49e7c16c0cc142a) --- .../jose/jaxrs/JwtAuthenticationFilterTest.java | 43 ++++++++++++++++++++++ .../cxf/rs/security/jose/jwt/JoseJwtConsumer.java | 4 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/test/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilterTest.java b/rt/rs/security/jose-parent/jose-jaxrs/src/test/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilterTest.java index a54002997ab..59ae573c68d 100644 --- a/rt/rs/security/jose-parent/jose-jaxrs/src/test/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilterTest.java +++ b/rt/rs/security/jose-parent/jose-jaxrs/src/test/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilterTest.java @@ -19,6 +19,7 @@ package org.apache.cxf.rs.security.jose.jaxrs; import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Collections; @@ -26,6 +27,10 @@ import java.util.Collections; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageImpl; import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactProducer; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.jose.jwt.JwtException; import org.apache.cxf.rs.security.jose.jwt.JwtToken; @@ -39,6 +44,7 @@ import static org.junit.Assert.fail; public class JwtAuthenticationFilterTest { private static final String AUDIENCE = "https://service.example.com"; + private static final byte[] ENCRYPTION_KEY = "0123456789abcdef".getBytes(StandardCharsets.UTF_8); @Before public void setUp() throws Exception { @@ -116,12 +122,49 @@ public class JwtAuthenticationFilterTest { } } + @Test + public void testEncryptedTokenAcceptedWithoutSignature() { + JwtAuthenticationFilter filter = createEncryptionOnlyFilter(); + filter.getJwtToken(encrypt(createClaims(null)), createDecryptionProvider(), null); + } + + @Test + public void testExpiredEncryptedTokenRejectedWithoutSignature() { + JwtAuthenticationFilter filter = createEncryptionOnlyFilter(); + JwtClaims claims = createClaims(null); + ZonedDateTime past = ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(10L); + claims.setIssuedAt(past.toEpochSecond()); + claims.setExpiryTime(past.plusMinutes(5L).toEpochSecond()); + try { + filter.getJwtToken(encrypt(claims), createDecryptionProvider(), null); + fail("Failure expected on an expired encrypted token"); + } catch (JwtException ex) { + // expected + } + } + private static JwtAuthenticationFilter createFilter() { JwtAuthenticationFilter filter = new JwtAuthenticationFilter(); filter.setValidateAudience(false); return filter; } + private static JwtAuthenticationFilter createEncryptionOnlyFilter() { + JwtAuthenticationFilter filter = createFilter(); + filter.setJwsRequired(false); + filter.setJweRequired(true); + return filter; + } + + private static String encrypt(JwtClaims claims) { + return new JweJwtCompactProducer(claims).encryptWith( + JweUtils.getDirectKeyJweEncryption(ENCRYPTION_KEY, ContentAlgorithm.A128GCM)); + } + + private static JweDecryptionProvider createDecryptionProvider() { + return JweUtils.getDirectKeyJweDecryption(ENCRYPTION_KEY, ContentAlgorithm.A128GCM); + } + private static JwtClaims createClaims(String issuer) { JwtClaims claims = new JwtClaims(); claims.setSubject("alice"); diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JoseJwtConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JoseJwtConsumer.java index f7cc09e2081..7b2c87a42f1 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JoseJwtConsumer.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JoseJwtConsumer.java @@ -51,7 +51,9 @@ public class JoseJwtConsumer extends AbstractJoseConsumer { } if (!isJwsRequired()) { - return jwtConsumer.decryptWith(theDecryptor); + JwtToken jwt = jwtConsumer.decryptWith(theDecryptor); + validateToken(jwt); + return jwt; } JweDecryptionOutput decOutput = theDecryptor.decrypt(wrappedJwtToken);
