This is an automated email from the ASF dual-hosted git repository.

chibenwa pushed a commit to branch 3.8.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 45e20f29ab6f25ea944712f9a9cd675d26332848
Author: Benoit TELLIER <[email protected]>
AuthorDate: Fri Jan 16 21:30:34 2026 +0100

    [ENHANCEMENT] Validate aud without introspect
---
 .../java/org/apache/james/jwt/JwtTokenVerifier.java  | 20 +++++++++-----------
 .../org/apache/james/jwt/OidcJwtTokenVerifier.java   | 19 ++++++++++++-------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwtTokenVerifier.java 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwtTokenVerifier.java
index 66daee29a2..f7a1909599 100644
--- 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwtTokenVerifier.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwtTokenVerifier.java
@@ -25,7 +25,6 @@ import java.util.Optional;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
 
 import io.jsonwebtoken.Claims;
@@ -33,7 +32,6 @@ import io.jsonwebtoken.Jws;
 import io.jsonwebtoken.JwtException;
 import io.jsonwebtoken.JwtParser;
 import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.MalformedJwtException;
 
 public class JwtTokenVerifier {
 
@@ -63,9 +61,15 @@ public class JwtTokenVerifier {
     }
 
     public <T> Optional<T> verifyAndExtractClaim(String token, String 
claimName, Class<T> returnType) {
-        return jwtParsers.stream()
-            .flatMap(parser -> verifyAndExtractClaim(token, claimName, 
returnType, parser).stream())
-            .findFirst();
+        return verify(token)
+            .flatMap(claims -> {
+                try {
+                    return Optional.ofNullable(claims.get(claimName, 
returnType));
+                } catch (JwtException e) {
+                    LOGGER.info("Failed Jwt verification", e);
+                    return Optional.empty();
+                }
+            });
     }
 
     public Optional<Claims> verify(String token) {
@@ -74,12 +78,6 @@ public class JwtTokenVerifier {
             .findFirst();
     }
 
-    private <T> Optional<T> verifyAndExtractClaim(String token, String 
claimName, Class<T> returnType, JwtParser parser) {
-        return retrieveClaims(token, parser)
-            .map(Throwing.function(claims -> 
Optional.ofNullable(claims.get(claimName, returnType))
-                .orElseThrow(() -> new MalformedJwtException("'" + claimName + 
"' field in token is mandatory"))));
-    }
-
     private Optional<Claims> retrieveClaims(String token, JwtParser parser) {
         try {
             Jws<Claims> jws = parser.parseClaimsJws(token);
diff --git 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcJwtTokenVerifier.java
 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcJwtTokenVerifier.java
index b1ca932fe8..dea93ea239 100644
--- 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcJwtTokenVerifier.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcJwtTokenVerifier.java
@@ -77,15 +77,20 @@ public class OidcJwtTokenVerifier {
 
     @VisibleForTesting
     Optional<String> verifySignatureAndExtractClaim(String jwtToken) {
-        Optional<String> unverifiedClaim = 
getClaimWithoutSignatureVerification(jwtToken, "kid");
-        PublicKeyProvider jwksPublicKeyProvider = unverifiedClaim
+        try {
+            Optional<String> unverifiedClaim = 
getClaimWithoutSignatureVerification(jwtToken, "kid");
+            PublicKeyProvider jwksPublicKeyProvider = unverifiedClaim
                 .map(kidValue -> 
JwksPublicKeyProvider.of(oidcSASLConfiguration.getJwksURL(), kidValue))
                 
.orElse(JwksPublicKeyProvider.of(oidcSASLConfiguration.getJwksURL()));
-        return new JwtTokenVerifier(jwksPublicKeyProvider)
-            .verify(jwtToken)
-            .filter(claims -> oidcSASLConfiguration.getAud().map(expectedAud 
-> claims.getAudience().contains(expectedAud))
-                .orElse(true)) // true if no aud is configured
-            .flatMap(claims -> 
Optional.ofNullable(claims.get(oidcSASLConfiguration.getClaim(), 
String.class)));
+            return new JwtTokenVerifier(jwksPublicKeyProvider)
+                .verify(jwtToken)
+                .filter(claims -> 
oidcSASLConfiguration.getAud().map(expectedAud -> 
claims.getAudience().contains(expectedAud))
+                    .orElse(true)) // true if no aud is configured
+                .flatMap(claims -> 
Optional.ofNullable(claims.get(oidcSASLConfiguration.getClaim(), 
String.class)));
+        } catch (JwtException e) {
+            LOGGER.info("Failed Jwt verification", e);
+            return Optional.empty();
+        }
     }
 
     private <T> Optional<T> getClaimWithoutSignatureVerification(String token, 
String claimName) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to