You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2026/06/24 06:58:05 UTC
(james-project) 02/05: [ENHANCEMENT] Validate aud without introspect
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 <bt...@linagora.com>
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: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org