This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new 4d8c9f4766c Enforce a default TTL in AbstractJwtAuthenticationFilter
so that tokens that don't have exp will be checked for expiration by default
(#3421)
4d8c9f4766c is described below
commit 4d8c9f4766cb630cf6e86be1867aa4952eea0130
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Mon Aug 31 16:55:32 2026 +0100
Enforce a default TTL in AbstractJwtAuthenticationFilter so that tokens
that don't have exp will be checked for expiration by default (#3421)
---
.../jaxrs/AbstractJwtAuthenticationFilter.java | 5 +++
.../apache/cxf/rs/security/jose/jwt/JwtUtils.java | 4 +--
.../cxf/rs/security/jose/jwt/JwtUtilsTest.java | 36 ++++++++++++++++++++++
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwtAuthenticationFilter.java
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwtAuthenticationFilter.java
index 673addd4d3f..7c99b7fd530 100644
---
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwtAuthenticationFilter.java
+++
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwtAuthenticationFilter.java
@@ -41,10 +41,15 @@ import org.apache.cxf.security.SecurityContext;
@Priority(Priorities.AUTHENTICATION)
public abstract class AbstractJwtAuthenticationFilter extends JoseJwtConsumer
implements ContainerRequestFilter {
protected static final Logger LOG =
LogUtils.getL7dLogger(AbstractJwtAuthenticationFilter.class);
+ private static final int DEFAULT_TTL_SECS = 300;
private String roleClaim;
private boolean validateAudience = true;
+ protected AbstractJwtAuthenticationFilter() {
+ setTtl(DEFAULT_TTL_SECS);
+ }
+
@Override
public void filter(ContainerRequestContext requestContext) throws
IOException {
String encodedJwtToken = getEncodedJwtToken(requestContext);
diff --git
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
index 10b08220a93..6c47611e8ab 100644
---
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
+++
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
@@ -157,8 +157,8 @@ public final class JwtUtils {
public static void validateTokenClaims(JwtClaims claims, int timeToLive,
int clockOffset,
boolean
validateAudienceRestriction) {
- // If we have no issued time then we need to have an expiry
- boolean expiredRequired = claims.getIssuedAt() == null;
+ // A positive TTL bounds the token age from its issued time.
+ boolean expiredRequired = claims.getIssuedAt() == null || timeToLive
<= 0;
validateJwtExpiry(claims, clockOffset, expiredRequired);
validateJwtNotBefore(claims, clockOffset, false);
diff --git
a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwt/JwtUtilsTest.java
b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwt/JwtUtilsTest.java
index af58d2d0e7c..dd8e5aa5392 100644
---
a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwt/JwtUtilsTest.java
+++
b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwt/JwtUtilsTest.java
@@ -213,5 +213,41 @@ public class JwtUtilsTest {
}
}
+ @org.junit.Test
+ public void testIssuedAtOnlyTokenRejectedWithoutTTL() {
+ JwtClaims claims = new JwtClaims();
+ claims.setSubject("alice");
+ claims.setIssuer("DoubleItSTSIssuer");
+ claims.setIssuedAt(ZonedDateTime.now(ZoneOffset.UTC).toEpochSecond());
+
+ try {
+ JwtUtils.validateTokenClaims(claims, 0, 0, false);
+ fail("Failure expected on an iat-only token with no configured
TTL");
+ } catch (JwtException ex) {
+ // expected
+ }
+ }
+
+ @org.junit.Test
+ public void testIssuedAtOnlyTokenAcceptedWithTTL() {
+ JwtClaims claims = new JwtClaims();
+ claims.setSubject("alice");
+ claims.setIssuer("DoubleItSTSIssuer");
+ claims.setIssuedAt(ZonedDateTime.now(ZoneOffset.UTC).toEpochSecond());
+
+ JwtUtils.validateTokenClaims(claims, 60, 0, false);
+ }
+
+ @org.junit.Test
+ public void testExpiryTokenAcceptedWithoutTTL() {
+ JwtClaims claims = new JwtClaims();
+ claims.setSubject("alice");
+ claims.setIssuer("DoubleItSTSIssuer");
+ ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
+ claims.setIssuedAt(now.toEpochSecond());
+ claims.setExpiryTime(now.plusMinutes(5L).toEpochSecond());
+
+ JwtUtils.validateTokenClaims(claims, 0, 0, false);
+ }
}