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);

Reply via email to