This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch coheigea/jwt-ttl in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 706550080500576ff6bb2a9fdc9cf430e303ae5e Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Mon Aug 31 14:58:26 2026 +0100 Enforce a default TTL in AbstractJwtAuthenticationFilter so that tokens that don't have exp will be checked for expiration by default --- .../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); + } }
