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

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

commit 095643daae512fdf5570b21d95a36c25ff9c2e4d
Author: Rene Cordier <[email protected]>
AuthorDate: Tue Dec 30 16:52:37 2025 +0700

    fixup! [ENHANCEMENT] OIDC SASL should validat AUD
---
 .../org/apache/james/jwt/OidcJwtTokenVerifier.java | 29 +++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

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 7f87132bb7..6f0be04e56 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
@@ -32,6 +32,11 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Header;
+import io.jsonwebtoken.Jwt;
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.Jwts;
 import reactor.core.publisher.Mono;
 
 public class OidcJwtTokenVerifier {
@@ -72,10 +77,32 @@ public class OidcJwtTokenVerifier {
 
     @VisibleForTesting
     Optional<String> verifySignatureAndExtractClaim(String jwtToken) {
-        return new 
JwtTokenVerifier(JwksPublicKeyProvider.of(oidcSASLConfiguration.getJwksURL()))
+        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)
             .verifyAndExtractClaim(jwtToken, oidcSASLConfiguration.getClaim(), 
String.class);
     }
 
+    private <T> Optional<T> getClaimWithoutSignatureVerification(String token, 
String claimName) {
+        int signatureIndex = token.lastIndexOf('.');
+        if (signatureIndex <= 0) {
+            return Optional.empty();
+        }
+        String nonSignedToken = token.substring(0, signatureIndex + 1);
+        try {
+            Jwt<Header, Claims> headerClaims = 
Jwts.parserBuilder().build().parseClaimsJwt(nonSignedToken);
+            T claim = (T) headerClaims.getHeader().get(claimName);
+            if (claim == null) {
+                return Optional.empty();
+            }
+            return Optional.of(claim);
+        } catch (JwtException e) {
+            return Optional.empty();
+        }
+    }
+
     @VisibleForTesting
     Publisher<String> verifyWithIntrospection(String jwtToken, 
IntrospectionEndpoint introspectionEndpoint) {
         return Mono.fromCallable(() -> 
verifySignatureAndExtractClaim(jwtToken))


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

Reply via email to