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