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

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

commit 3e9a98b148a7500a9b0f877be90037afd6a6921d
Author: Amichai Rothman <amich...@amichais.net>
AuthorDate: Wed Jun 25 19:33:42 2025 +0300

    [UPGRADE] upgrade jjwt to 0.12.6
---
 pom.xml                                            |   2 +-
 .../apache/james/jwt/DefaultPublicKeyProvider.java |   9 ++
 .../apache/james/jwt/JwksPublicKeyProvider.java    |  21 ++---
 .../org/apache/james/jwt/JwtTokenVerifier.java     | 105 +++++++++++++++------
 .../org/apache/james/jwt/OidcJwtTokenVerifier.java |  30 +-----
 .../org/apache/james/jwt/PublicKeyProvider.java    |  17 ++++
 .../james/jwt/JwksPublicKeyProviderTest.java       |  16 ++--
 .../apache/james/jwt/OidcJwtTokenVerifierTest.java |  40 +++++---
 8 files changed, 144 insertions(+), 96 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6d1f31ae8b..dc7bd4b7ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -651,7 +651,7 @@
         <jackson.databind.version>2.19.1</jackson.databind.version>
         <feign.version>13.6</feign.version>
         <feign-form.version>3.8.0</feign-form.version>
-        <jjwt.version>0.11.5</jjwt.version>
+        <jjwt.version>0.12.6</jjwt.version>
         <metrics.version>4.2.32</metrics.version>
         <testcontainers.version>1.21.1</testcontainers.version>
         <es-reporter.version>6.0.0-RC3</es-reporter.version>
diff --git 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/DefaultPublicKeyProvider.java
 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/DefaultPublicKeyProvider.java
index 2d4ecd739c..8627b1526b 100644
--- 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/DefaultPublicKeyProvider.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/DefaultPublicKeyProvider.java
@@ -20,6 +20,7 @@ package org.apache.james.jwt;
 
 import java.security.PublicKey;
 import java.util.List;
+import java.util.Optional;
 
 import com.google.common.collect.ImmutableList;
 
@@ -45,4 +46,12 @@ public class DefaultPublicKeyProvider implements 
PublicKeyProvider {
         return keys;
     }
 
+    @Override
+    public Optional<PublicKey> get(String kid) throws 
MissingOrInvalidKeyException {
+        // TODO: pick a simple or standard way of calculating a unique kid for 
each public key
+        // that can be calculated by the user when generating the JWT
+        // and calculated or looked up here for comparison.
+        return Optional.empty();
+    }
+
 }
diff --git 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwksPublicKeyProvider.java
 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwksPublicKeyProvider.java
index 0074981c9f..a9ca63fe53 100644
--- 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwksPublicKeyProvider.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/JwksPublicKeyProvider.java
@@ -38,35 +38,28 @@ import com.google.common.collect.ImmutableList;
 public class JwksPublicKeyProvider implements PublicKeyProvider {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JwksPublicKeyProvider.class);
 
-    public static JwksPublicKeyProvider of(URL jwksURL, String kid) {
-        return new JwksPublicKeyProvider(jwksURL, Optional.of(kid));
-    }
-
     public static JwksPublicKeyProvider of(URL jwksURL) {
-        return new JwksPublicKeyProvider(jwksURL, Optional.empty());
+        return new JwksPublicKeyProvider(jwksURL);
     }
 
     private final UrlJwkProvider jwkProvider;
-    private final Optional<String> kid;
 
-    private JwksPublicKeyProvider(URL jwksURL, Optional<String> kid) {
+    private JwksPublicKeyProvider(URL jwksURL) {
         Preconditions.checkNotNull(jwksURL);
-        Preconditions.checkNotNull(kid);
         this.jwkProvider = new UrlJwkProvider(jwksURL);
-        this.kid = kid;
     }
 
     @Override
     public List<PublicKey> get() throws MissingOrInvalidKeyException {
-        return kid.map(this::get)
-            .orElse(getAllFromProvider());
+        return getAllFromProvider();
     }
 
-    public List<PublicKey> get(String kid) throws MissingOrInvalidKeyException 
{
+    @Override
+    public Optional<PublicKey> get(String kid) throws 
MissingOrInvalidKeyException {
         try {
-            return ImmutableList.of(jwkProvider.get(kid).getPublicKey());
+            return Optional.of(jwkProvider.get(kid).getPublicKey());
         } catch (SigningKeyNotFoundException notFoundException) {
-            return ImmutableList.of();
+            return Optional.empty();
         } catch (JwkException e) {
             LOGGER.error("Can't get publicKeys has kid = {} from jwksURL.", 
kid, e);
             throw new MissingOrInvalidKeyException();
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 878a8a6c76..ae197d8e68 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
@@ -18,43 +18,75 @@
  ****************************************************************/
 package org.apache.james.jwt;
 
-import java.security.PublicKey;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 
 import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.CompressionCodecResolver;
 import io.jsonwebtoken.Jws;
 import io.jsonwebtoken.JwtException;
 import io.jsonwebtoken.JwtParser;
 import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.Locator;
 import io.jsonwebtoken.MalformedJwtException;
-import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver;
+import io.jsonwebtoken.io.CompressionAlgorithm;
 
 public class JwtTokenVerifier {
-    private static final CompressionCodecResolver 
DEFAULT_COMPRESSION_CODEC_RESOLVER = new DefaultCompressionCodecResolver();
-    private static final CompressionCodecResolver 
SECURE_COMPRESSION_CODEC_RESOLVER = header -> {
-        if (Optional.ofNullable(header.getCompressionAlgorithm()).isPresent()) 
{
-            throw new RuntimeException("Rejecting a ZIP JWT. Usage of ZIPPED 
JWT can result in " +
-                "excessive memory usage with malicious JWT tokens. To activate 
support for ZIPPed" +
-                "JWT please run James with the -Djames.jwt.zip.allow=true 
system property.");
-        }
-        return 
DEFAULT_COMPRESSION_CODEC_RESOLVER.resolveCompressionCodec(header);
-    };
-    private static final boolean allowZipJWT = 
Optional.ofNullable(System.getProperty("james.jwt.zip.allow"))
+    static boolean allowZipJWT = 
Optional.ofNullable(System.getProperty("james.jwt.zip.allow"))
         .map(Boolean::parseBoolean)
         .orElse(false);
-    @VisibleForTesting
-    static CompressionCodecResolver CONFIGURED_COMPRESSION_CODEC_RESOLVER = 
Optional.of(allowZipJWT)
-        .filter(b -> b)
-        .map(any -> DEFAULT_COMPRESSION_CODEC_RESOLVER)
-        .orElse(SECURE_COMPRESSION_CODEC_RESOLVER);
+
+    /**
+     * A CompressionAlgorithm that delegates to another compression algorithm
+     * if compression is allowed, or throws exceptions if not.
+     */
+    private static class SecureCompressionAlgorithm implements 
CompressionAlgorithm {
+        String id;
+        CompressionAlgorithm delegate;
+
+        public SecureCompressionAlgorithm(String id, CompressionAlgorithm 
delegate) {
+            this.id = id;
+            this.delegate = delegate;
+        }
+
+        private void validate() {
+            if (!allowZipJWT) {
+                throw new RuntimeException("Rejecting a ZIP JWT. Usage of 
ZIPPED JWT can result in " +
+                    "excessive memory usage with malicious JWT tokens. To 
activate support for ZIPPed" +
+                    "JWT please run James with the -Djames.jwt.zip.allow=true 
system property.");
+            }
+        }
+
+        @Override
+        public String getId() {
+            return id;
+        }
+
+        @Override
+        public OutputStream compress(OutputStream out) {
+            validate();
+            return delegate.compress(out);
+        }
+
+        @Override
+        public InputStream decompress(InputStream in) {
+            validate();
+            return delegate.decompress(in);
+        }
+    }
+
+    // wrap all supported compression algorithms with 'secure' ones that throw 
exception if disabled
+    private static final List<SecureCompressionAlgorithm> 
SECURE_COMPRESSION_ALGORITHMS =
+        Jwts.ZIP.get().values().stream().map(c -> new 
SecureCompressionAlgorithm(c.getId(), c)).toList();
 
     public interface Factory {
         JwtTokenVerifier create();
@@ -67,12 +99,19 @@ public class JwtTokenVerifier {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JwtTokenVerifier.class);
 
+    private final JwtParser kidJwtParser;
     private final List<JwtParser> jwtParsers;
 
     public JwtTokenVerifier(PublicKeyProvider pubKeyProvider) {
+        // one parser that performs key lookup by kid
+        this.kidJwtParser = toImmutableJwtParser(jwtHeaders -> {
+            String kid = Objects.requireNonNull((String)jwtHeaders.get("kid"));
+            return pubKeyProvider.get(kid).orElse(null);
+        });
+        // a list of parsers, one for each of the provider's keys
         this.jwtParsers = pubKeyProvider.get()
             .stream()
-            .map(this::toImmutableJwtParser)
+            .map(key -> toImmutableJwtParser(jwtHeaders -> key))
             .collect(ImmutableList.toImmutableList());
     }
 
@@ -82,22 +121,28 @@ 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();
+        try {
+            // if the token contains a kid, verify only with the corresponding 
key (or fail)
+            return verifyAndExtractClaim(token, claimName, returnType, 
kidJwtParser);
+        } catch (NullPointerException npe) { // our own key locator throws NPE 
when there is no kid
+            // if token does not specify kid, fallback to trying all keys
+            return jwtParsers.stream()
+                .flatMap(parser -> verifyAndExtractClaim(token, claimName, 
returnType, parser).stream())
+                .findFirst();
+        }
     }
 
     private <T> Optional<T> verifyAndExtractClaim(String token, String 
claimName, Class<T> returnType, JwtParser parser) {
         try {
-            Jws<Claims> jws = parser.parseClaimsJws(token);
+            Jws<Claims> jws = parser.parseSignedClaims(token);
             T claim = jws
-                .getBody()
+                .getPayload()
                 .get(claimName, returnType);
             if (claim == null) {
                 throw new MalformedJwtException("'" + claimName + "' field in 
token is mandatory");
             }
             return Optional.of(claim);
-        } catch (JwtException e) {
+        } catch (JwtException e) { // also if kid was given but our locator 
didn't find the corresponding key
             LOGGER.info("Failed Jwt verification", e);
             return Optional.empty();
         }
@@ -114,10 +159,10 @@ public class JwtTokenVerifier {
         }
     }
 
-    private JwtParser toImmutableJwtParser(PublicKey publicKey) {
-        return Jwts.parserBuilder()
-            .setSigningKey(publicKey)
-            .setCompressionCodecResolver(CONFIGURED_COMPRESSION_CODEC_RESOLVER)
+    private JwtParser toImmutableJwtParser(Locator<Key> keyLocator) {
+        return Jwts.parser()
+            .keyLocator(keyLocator)
+            .zip().add(SECURE_COMPRESSION_ALGORITHMS).and()
             .build();
     }
 }
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 35ba364dca..63124ca253 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
@@ -26,40 +26,14 @@ import 
org.apache.james.jwt.introspection.IntrospectionEndpoint;
 import org.apache.james.jwt.introspection.TokenIntrospectionResponse;
 import org.reactivestreams.Publisher;
 
-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 {
     public static final CheckTokenClient CHECK_TOKEN_CLIENT = new 
DefaultCheckTokenClient();
 
     public static Optional<String> verifySignatureAndExtractClaim(String 
jwtToken, URL jwksURL, String claimName) {
-        Optional<String> unverifiedClaim = 
getClaimWithoutSignatureVerification(jwtToken, "kid");
-        PublicKeyProvider jwksPublicKeyProvider = unverifiedClaim
-            .map(kidValue -> JwksPublicKeyProvider.of(jwksURL, kidValue))
-            .orElse(JwksPublicKeyProvider.of(jwksURL));
-        return new 
JwtTokenVerifier(jwksPublicKeyProvider).verifyAndExtractClaim(jwtToken, 
claimName, String.class);
-    }
-
-    public static <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();
-        }
+        return new JwtTokenVerifier(JwksPublicKeyProvider.of(jwksURL))
+            .verifyAndExtractClaim(jwtToken, claimName, String.class);
     }
 
     public static Publisher<String> verifyWithIntrospection(String jwtToken, 
URL jwksURL, String claimName, IntrospectionEndpoint introspectionEndpoint) {
diff --git 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/PublicKeyProvider.java
 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/PublicKeyProvider.java
index c87f25bfe2..b5cd772771 100644
--- 
a/server/protocols/jwt/src/main/java/org/apache/james/jwt/PublicKeyProvider.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/PublicKeyProvider.java
@@ -21,7 +21,24 @@ package org.apache.james.jwt;
 
 import java.security.PublicKey;
 import java.util.List;
+import java.util.Optional;
 
 public interface PublicKeyProvider {
+
+    /**
+     * Returns all keys managed by this provider.
+     *
+     * @return all keys managed by this provider
+     * @throws MissingOrInvalidKeyException if an error occurred while getting 
the keys
+     */
     List<PublicKey> get() throws MissingOrInvalidKeyException;
+
+    /**
+     * Returns the key corresponding to the given kid.
+     *
+     * @param kid the kid value
+     * @return the key corresponding to the given kid, or empty if not found
+     * @throws MissingOrInvalidKeyException if an error occurred while getting 
the key
+     */
+    Optional<PublicKey> get(String kid) throws MissingOrInvalidKeyException;
 }
diff --git 
a/server/protocols/jwt/src/test/java/org/apache/james/jwt/JwksPublicKeyProviderTest.java
 
b/server/protocols/jwt/src/test/java/org/apache/james/jwt/JwksPublicKeyProviderTest.java
index 68da3f5845..7351d4bcf3 100644
--- 
a/server/protocols/jwt/src/test/java/org/apache/james/jwt/JwksPublicKeyProviderTest.java
+++ 
b/server/protocols/jwt/src/test/java/org/apache/james/jwt/JwksPublicKeyProviderTest.java
@@ -29,7 +29,6 @@ import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.security.PublicKey;
 import java.security.interfaces.RSAPublicKey;
-import java.util.List;
 
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -93,18 +92,17 @@ class JwksPublicKeyProviderTest {
 
     @Test
     void getShouldSuccessWhenKeyProvided() {
-        PublicKeyProvider testee = JwksPublicKeyProvider.of(getJwksURL(), 
"wu-9VZEr0gHF986PYPVzvU-5IP1q26EzzQVK_sjG29Q");
-        List<PublicKey> publicKeys = testee.get();
+        PublicKeyProvider testee = JwksPublicKeyProvider.of(getJwksURL());
+        PublicKey publicKey = 
testee.get("wu-9VZEr0gHF986PYPVzvU-5IP1q26EzzQVK_sjG29Q").get();
         SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(publicKeys).hasSize(1);
-            
softly.assertThat(publicKeys.get(0)).isInstanceOf(RSAPublicKey.class);
+            softly.assertThat(publicKey).isInstanceOf(RSAPublicKey.class);
         });
     }
 
     @Test
     void getShouldReturnEmptyWhenKeyNotProvided() {
-        PublicKeyProvider testee = JwksPublicKeyProvider.of(getJwksURL(), 
"notfound");
-        assertThat(testee.get()).isEmpty();
+        PublicKeyProvider testee = JwksPublicKeyProvider.of(getJwksURL());
+        assertThat(testee.get("notfound")).isEmpty();
     }
 
     @Test
@@ -114,8 +112,8 @@ class JwksPublicKeyProviderTest {
             .respond(HttpResponse.response().withStatusCode(200)
                 .withBody("invalid body", StandardCharsets.UTF_8));
 
-        PublicKeyProvider testee = JwksPublicKeyProvider.of(new 
URI(String.format("http://127.0.0.1:%s/invalid";, 
mockServer.getLocalPort())).toURL(),
-            "wu-9VZEr0gHF986PYPVzvU-5IP1q26EzzQVK_sjG29Q");
+        PublicKeyProvider testee = JwksPublicKeyProvider.of(
+            new URI(String.format("http://127.0.0.1:%s/invalid";, 
mockServer.getLocalPort())).toURL());
         assertThatThrownBy(testee::get)
             .isInstanceOf(MissingOrInvalidKeyException.class);
     }
diff --git 
a/server/protocols/jwt/src/test/java/org/apache/james/jwt/OidcJwtTokenVerifierTest.java
 
b/server/protocols/jwt/src/test/java/org/apache/james/jwt/OidcJwtTokenVerifierTest.java
index 9446aa69b5..0c9c1f597a 100644
--- 
a/server/protocols/jwt/src/test/java/org/apache/james/jwt/OidcJwtTokenVerifierTest.java
+++ 
b/server/protocols/jwt/src/test/java/org/apache/james/jwt/OidcJwtTokenVerifierTest.java
@@ -30,6 +30,11 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Optional;
 
 import org.apache.james.jwt.introspection.IntrospectionEndpoint;
@@ -43,10 +48,8 @@ import org.mockserver.integration.ClientAndServer;
 import org.mockserver.model.HttpRequest;
 import org.mockserver.model.HttpResponse;
 
-import io.jsonwebtoken.CompressionCodecs;
 import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver;
+import io.jsonwebtoken.io.Decoders;
 import reactor.core.publisher.Mono;
 
 class OidcJwtTokenVerifierTest {
@@ -93,12 +96,18 @@ class OidcJwtTokenVerifierTest {
         });
     }
 
+    private static PrivateKey toPrivateKey(String base64Key) throws 
NoSuchAlgorithmException, InvalidKeySpecException {
+        byte[] keyBytes = Decoders.BASE64.decode(base64Key.replace("\n", ""));
+        KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
+        return kf.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
+    }
+
     @Test
-    void shouldRejectZippedJWTByDefault() {
+    void shouldRejectZippedJWTByDefault() throws NoSuchAlgorithmException, 
InvalidKeySpecException {
         String jws = Jwts.builder()
             .claim("kid", "a".repeat(100))
-            .compressWith(CompressionCodecs.DEFLATE)
-            .signWith(SignatureAlgorithm.HS256, 
OidcTokenFixture.PRIVATE_KEY_BASE64.replace("\n", ""))
+            .compressWith(Jwts.ZIP.DEF)
+            .signWith(toPrivateKey(OidcTokenFixture.PRIVATE_KEY_BASE64), 
Jwts.SIG.RS256)
             .compact();
 
         assertThatThrownBy(() -> 
OidcJwtTokenVerifier.verifySignatureAndExtractClaim(jws, getJwksURL(), "kid"))
@@ -107,17 +116,21 @@ class OidcJwtTokenVerifierTest {
     }
 
     @Test
-    void shouldAcceptZippedJWTWhenConfigured() {
+    void shouldAcceptZippedJWTWhenConfigured() throws 
NoSuchAlgorithmException, InvalidKeySpecException {
         String jws = Jwts.builder()
             .claim("kid", "a".repeat(100))
-            .compressWith(CompressionCodecs.DEFLATE)
-            .signWith(SignatureAlgorithm.HS256, 
OidcTokenFixture.PRIVATE_KEY_BASE64.replace("\n", ""))
+            .compressWith(Jwts.ZIP.DEF)
+            .signWith(toPrivateKey(OidcTokenFixture.PRIVATE_KEY_BASE64), 
Jwts.SIG.RS256)
             .compact();
 
-        JwtTokenVerifier.CONFIGURED_COMPRESSION_CODEC_RESOLVER = new 
DefaultCompressionCodecResolver();
-
-        assertThatCode(() -> 
OidcJwtTokenVerifier.verifySignatureAndExtractClaim(jws, getJwksURL(), "kid"))
-            .doesNotThrowAnyException();
+        boolean prev = JwtTokenVerifier.allowZipJWT;
+        JwtTokenVerifier.allowZipJWT = true;
+        try {
+            assertThatCode(() -> 
OidcJwtTokenVerifier.verifySignatureAndExtractClaim(jws, getJwksURL(), "kid"))
+                .doesNotThrowAnyException();
+        } finally {
+            JwtTokenVerifier.allowZipJWT = prev;
+        }
     }
 
     @Test
@@ -132,7 +145,6 @@ class OidcJwtTokenVerifierTest {
             .isEmpty();
     }
 
-
     @Test
     void verifyAndClaimShouldReturnEmptyWhenInvalidToken() {
         
assertThat(OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.INVALID_TOKEN,
 getJwksURL(), "email_address"))


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to