From 5f7155bfc75a488fdd91e983ac4e947d80f74950 Mon Sep 17 00:00:00 2001 From: Joe Grandja <10884212+jgrandja@users.noreply.github.com> Date: Wed, 14 May 2025 05:21:00 -0400 Subject: [PATCH] Implement internal cache in JtiClaimValidator Closes gh-17107 --- .../jwt/DPoPProofJwtDecoderFactory.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofJwtDecoderFactory.java b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofJwtDecoderFactory.java index 509d0d25eb..6970b449c6 100644 --- a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofJwtDecoderFactory.java +++ b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofJwtDecoderFactory.java @@ -18,12 +18,12 @@ package org.springframework.security.oauth2.jwt; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -import java.time.Clock; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Base64; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import com.nimbusds.jose.JOSEException; @@ -146,7 +146,7 @@ public final class DPoPProofJwtDecoderFactory implements JwtDecoderFactory { - private static final Map jtiCache = new ConcurrentHashMap<>(); + private static final Map JTI_CACHE = Collections.synchronizedMap(new JtiCache()); @Override public OAuth2TokenValidatorResult validate(Jwt jwt) { @@ -166,8 +166,8 @@ public final class DPoPProofJwtDecoderFactory implements JwtDecoderFactory { + + private static final int MAX_SIZE = 1000; + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + if (size() > MAX_SIZE) { + return true; + } + Instant expiry = Instant.ofEpochMilli(eldest.getValue()); + return Instant.now().isAfter(expiry); + } + + } + } }