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]
