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 547a3ccf87baa41503d46e06ca7f311601c18daa
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Dec 8 14:11:29 2025 +0100

    [ENHANCEMENT] OIDC SASL code refactoring
    
     - Mutualize code for choosing how code shall be validated between IMAP and 
SMTP
     - Turn OidcJwtTokenVerifier as a class
     - Have SASL configuration as a member in order to limit count of arguments
---
 protocols/api/pom.xml                              |  4 +
 .../apache/james/imap/api/process/ImapSession.java |  2 +-
 .../apache/james/imap/encode/FakeImapSession.java  |  2 +-
 .../imap/processor/AuthenticateProcessor.java      | 39 +--------
 .../protocols/lmtp/LMTPConfigurationImpl.java      |  2 +-
 .../james/protocols/smtp/SMTPConfiguration.java    |  2 +-
 .../protocols/smtp/SMTPConfigurationImpl.java      |  2 +-
 .../protocols/smtp/core/esmtp/AuthCmdHandler.java  |  2 +-
 .../apache/james/protocols/smtp/hook/AuthHook.java |  2 +-
 server/protocols/jwt/pom.xml                       |  4 +
 .../org/apache/james/jwt/OidcJwtTokenVerifier.java | 55 +++++++++++--
 .../apache/james/jwt}/OidcSASLConfiguration.java   | 96 +++++++++++++++++++++-
 .../apache/james/jwt/OidcJwtTokenVerifierTest.java | 85 ++++++++++++-------
 server/protocols/protocols-imap4/pom.xml           |  2 +-
 .../apache/james/imapserver/netty/IMAPServer.java  |  2 +-
 .../james/imapserver/netty/NettyImapSession.java   |  2 +-
 .../apache/james/lmtpserver/netty/LMTPServer.java  |  2 +-
 server/protocols/protocols-smtp/pom.xml            |  2 +-
 .../james/smtpserver/UsersRepositoryAuthHook.java  | 40 +--------
 .../apache/james/smtpserver/netty/SMTPServer.java  |  2 +-
 20 files changed, 222 insertions(+), 127 deletions(-)

diff --git a/protocols/api/pom.xml b/protocols/api/pom.xml
index 0b33366bea..03cb72c367 100644
--- a/protocols/api/pom.xml
+++ b/protocols/api/pom.xml
@@ -37,6 +37,10 @@
             <groupId>${james.groupId}</groupId>
             <artifactId>james-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-jwt</artifactId>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
index 81a93d0194..c3da9c5841 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
@@ -28,9 +28,9 @@ import javax.net.ssl.SSLSession;
 import org.apache.commons.text.RandomStringGenerator;
 import org.apache.james.core.Username;
 import org.apache.james.imap.api.ImapSessionState;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.protocols.api.CommandDetectionSession;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 
 import reactor.core.publisher.Mono;
 
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
index 44eb77d5ed..2fcb506b8e 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
@@ -33,7 +33,7 @@ import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapLineHandler;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.util.concurrent.NamedThreadFactory;
 
 import reactor.core.publisher.Mono;
diff --git 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
index 40de07069c..937cf8fd11 100644
--- 
a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
+++ 
b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
@@ -40,11 +39,10 @@ import 
org.apache.james.imap.message.request.AuthenticateRequest;
 import org.apache.james.imap.message.request.IRAuthenticateRequest;
 import org.apache.james.imap.message.response.AuthenticateResponse;
 import org.apache.james.jwt.OidcJwtTokenVerifier;
-import org.apache.james.jwt.introspection.IntrospectionEndpoint;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.protocols.api.OIDCSASLParser;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,8 +50,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
-import reactor.core.publisher.Mono;
-
 /**
  * Processor which handles the AUTHENTICATE command. Only authtype of PLAIN is 
supported ATM.
  */
@@ -210,7 +206,7 @@ public class AuthenticateProcessor extends 
AbstractAuthProcessor<AuthenticateReq
 
     private void doOAuth(OIDCSASLParser.OIDCInitialResponse 
oidcInitialResponse, OidcSASLConfiguration oidcSASLConfiguration,
                          ImapSession session, ImapRequest request, Responder 
responder) {
-        validateToken(oidcSASLConfiguration, oidcInitialResponse.getToken())
+        new 
OidcJwtTokenVerifier(oidcSASLConfiguration).validateToken(oidcInitialResponse.getToken())
             .ifPresentOrElse(authenticatedUser -> {
                 Username associatedUser = 
Username.of(oidcInitialResponse.getAssociatedUser());
                 if (!associatedUser.equals(authenticatedUser)) {
@@ -224,37 +220,6 @@ public class AuthenticateProcessor extends 
AbstractAuthProcessor<AuthenticateReq
             }, () -> manageFailureCount(session, request, responder));
     }
 
-    private Optional<Username> validateToken(OidcSASLConfiguration 
oidcSASLConfiguration, String token) {
-        if (oidcSASLConfiguration.isCheckTokenByIntrospectionEndpoint()) {
-            return validTokenWithIntrospection(oidcSASLConfiguration, token);
-        } else if (oidcSASLConfiguration.isCheckTokenByUserinfoEndpoint()) {
-            return validTokenWithUserInfo(oidcSASLConfiguration, token);
-        } else {
-            return OidcJwtTokenVerifier.verifySignatureAndExtractClaim(token, 
oidcSASLConfiguration.getJwksURL(), oidcSASLConfiguration.getClaim())
-                .map(Username::of);
-        }
-    }
-
-    private static Optional<Username> 
validTokenWithUserInfo(OidcSASLConfiguration oidcSASLConfiguration, String 
token) {
-        return Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(token,
-                oidcSASLConfiguration.getJwksURL(),
-                oidcSASLConfiguration.getClaim(),
-                oidcSASLConfiguration.getUserInfoEndpoint().orElseThrow()))
-            .blockOptional()
-            .map(Username::of);
-    }
-
-    private static Optional<Username> 
validTokenWithIntrospection(OidcSASLConfiguration oidcSASLConfiguration, String 
token) {
-        return Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(token,
-                oidcSASLConfiguration.getJwksURL(),
-                oidcSASLConfiguration.getClaim(),
-                oidcSASLConfiguration.getIntrospectionEndpoint()
-                    .map(endpoint -> new IntrospectionEndpoint(endpoint, 
oidcSASLConfiguration.getIntrospectionEndpointAuthorization()))
-                    .orElseThrow()))
-            .blockOptional()
-            .map(Username::of);
-    }
-
     private static String extractInitialClientResponse(byte[] data) {
         // cut of the CRLF
         return new String(data, 0, data.length - 2, StandardCharsets.US_ASCII);
diff --git 
a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/LMTPConfigurationImpl.java
 
b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/LMTPConfigurationImpl.java
index 9202c26404..f7eb23442a 100644
--- 
a/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/LMTPConfigurationImpl.java
+++ 
b/protocols/lmtp/src/test/java/org/apache/james/protocols/lmtp/LMTPConfigurationImpl.java
@@ -20,7 +20,7 @@ package org.apache.james.protocols.lmtp;
 
 import java.util.Optional;
 
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 
 public class LMTPConfigurationImpl extends LMTPConfiguration {
 
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfiguration.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfiguration.java
index acbf2dc604..f66106d482 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfiguration.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfiguration.java
@@ -23,7 +23,7 @@ package org.apache.james.protocols.smtp;
 
 import java.util.Optional;
 
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.protocols.api.ProtocolConfiguration;
 
 
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfigurationImpl.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfigurationImpl.java
index 1fb081f546..12e4f4bbee 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfigurationImpl.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/SMTPConfigurationImpl.java
@@ -22,7 +22,7 @@ package org.apache.james.protocols.smtp;
 
 import java.util.Optional;
 
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.protocols.api.ProtocolConfigurationImpl;
 
 /**
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java
index b3f1915a32..2285f615de 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java
@@ -35,7 +35,7 @@ import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.james.core.Username;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.protocols.api.Request;
 import org.apache.james.protocols.api.Response;
 import org.apache.james.protocols.api.handler.CommandHandler;
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/hook/AuthHook.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/hook/AuthHook.java
index 8351eb2367..3a7234356c 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/hook/AuthHook.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/hook/AuthHook.java
@@ -19,7 +19,7 @@
 package org.apache.james.protocols.smtp.hook;
 
 import org.apache.james.core.Username;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.protocols.smtp.SMTPSession;
 
 /**
diff --git a/server/protocols/jwt/pom.xml b/server/protocols/jwt/pom.xml
index 6e1c300b10..17d59d1135 100644
--- a/server/protocols/jwt/pom.xml
+++ b/server/protocols/jwt/pom.xml
@@ -32,6 +32,10 @@
     <name>Apache James :: Server :: JWT</name>
 
     <dependencies>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-core</artifactId>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
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..83bd172846 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
@@ -22,10 +22,13 @@ package org.apache.james.jwt;
 import java.net.URL;
 import java.util.Optional;
 
+import org.apache.james.core.Username;
 import org.apache.james.jwt.introspection.IntrospectionEndpoint;
 import org.apache.james.jwt.introspection.TokenIntrospectionResponse;
 import org.reactivestreams.Publisher;
 
+import com.google.common.annotations.VisibleForTesting;
+
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Header;
 import io.jsonwebtoken.Jwt;
@@ -62,22 +65,62 @@ public class OidcJwtTokenVerifier {
         }
     }
 
-    public static Publisher<String> verifyWithIntrospection(String jwtToken, 
URL jwksURL, String claimName, IntrospectionEndpoint introspectionEndpoint) {
-        return Mono.fromCallable(() -> 
verifySignatureAndExtractClaim(jwtToken, jwksURL, claimName))
+    private final OidcSASLConfiguration oidcSASLConfiguration;
+
+    public OidcJwtTokenVerifier(OidcSASLConfiguration oidcSASLConfiguration) {
+        this.oidcSASLConfiguration = oidcSASLConfiguration;
+    }
+
+    public Optional<Username> validateToken(String token) {
+        if (oidcSASLConfiguration.isCheckTokenByIntrospectionEndpoint()) {
+            return validTokenWithIntrospection(token);
+        } else if (oidcSASLConfiguration.isCheckTokenByUserinfoEndpoint()) {
+            return validTokenWithUserInfo(token);
+        } else {
+            return verifySignatureAndExtractClaim(token)
+                .map(Username::of);
+        }
+    }
+
+    private Optional<Username> validTokenWithUserInfo(String token) {
+        return Mono.from(verifyWithUserinfo(token, 
oidcSASLConfiguration.getUserInfoEndpoint().orElseThrow()))
+            .blockOptional()
+            .map(Username::of);
+    }
+
+    private Optional<Username> validTokenWithIntrospection(String token) {
+        return Mono.from(verifyWithIntrospection(token,
+                oidcSASLConfiguration.getIntrospectionEndpoint()
+                    .map(endpoint -> new IntrospectionEndpoint(endpoint, 
oidcSASLConfiguration.getIntrospectionEndpointAuthorization()))
+                    .orElseThrow()))
+            .blockOptional()
+            .map(Username::of);
+    }
+
+    @VisibleForTesting
+    Optional<String> verifySignatureAndExtractClaim(String jwtToken) {
+        return new 
JwtTokenVerifier(JwksPublicKeyProvider.of(oidcSASLConfiguration.getJwksURL()))
+            .verifyAndExtractClaim(jwtToken, oidcSASLConfiguration.getClaim(), 
String.class);
+    }
+
+    @VisibleForTesting
+    Publisher<String> verifyWithIntrospection(String jwtToken, 
IntrospectionEndpoint introspectionEndpoint) {
+        return Mono.fromCallable(() -> 
verifySignatureAndExtractClaim(jwtToken))
             .flatMap(optional -> 
optional.map(Mono::just).orElseGet(Mono::empty))
             .flatMap(claimResult -> 
Mono.from(CHECK_TOKEN_CLIENT.introspect(introspectionEndpoint, jwtToken))
                 .filter(TokenIntrospectionResponse::active)
-                .filter(tokenIntrospectionResponse -> 
tokenIntrospectionResponse.claimByPropertyName(claimName)
+                .filter(tokenIntrospectionResponse -> 
tokenIntrospectionResponse.claimByPropertyName(oidcSASLConfiguration.getClaim())
                     .map(claim -> claim.equals(claimResult))
                     .orElse(false))
                 .map(activeResponse -> claimResult));
     }
 
-    public static Publisher<String> verifyWithUserinfo(String jwtToken, URL 
jwksURL, String claimName, URL userinfoEndpoint) {
-        return Mono.fromCallable(() -> 
verifySignatureAndExtractClaim(jwtToken, jwksURL, claimName))
+    @VisibleForTesting
+   Publisher<String> verifyWithUserinfo(String jwtToken, URL userinfoEndpoint) 
{
+        return Mono.fromCallable(() -> 
verifySignatureAndExtractClaim(jwtToken))
             .flatMap(optional -> 
optional.map(Mono::just).orElseGet(Mono::empty))
             .flatMap(claimResult -> 
Mono.from(CHECK_TOKEN_CLIENT.userInfo(userinfoEndpoint, jwtToken))
-                .filter(userinfoResponse -> 
userinfoResponse.claimByPropertyName(claimName)
+                .filter(userinfoResponse -> 
userinfoResponse.claimByPropertyName(oidcSASLConfiguration.getClaim())
                     .map(claim -> claim.equals(claimResult))
                     .orElse(false))
                 .map(userinfoResponse -> claimResult));
diff --git 
a/protocols/api/src/main/java/org/apache/james/protocols/api/OidcSASLConfiguration.java
 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcSASLConfiguration.java
similarity index 56%
rename from 
protocols/api/src/main/java/org/apache/james/protocols/api/OidcSASLConfiguration.java
rename to 
server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcSASLConfiguration.java
index 232ca8afcd..403a33f966 100644
--- 
a/protocols/api/src/main/java/org/apache/james/protocols/api/OidcSASLConfiguration.java
+++ 
b/server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcSASLConfiguration.java
@@ -17,7 +17,7 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.james.protocols.api;
+package org.apache.james.jwt;
 
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -25,11 +25,95 @@ import java.util.Optional;
 
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
 public class OidcSASLConfiguration {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(OidcSASLConfiguration.class);
+
+    private static final boolean FORCE_INTROSPECT = 
Boolean.parseBoolean(System.getProperty("james.sasl.oidc.force.introspect", 
"true"));
+
+    @VisibleForTesting
+    static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private URL jwksURL;
+        private String claim;
+        private URL oidcConfigurationURL;
+        private String scope;
+        private Optional<URL> introspectionEndpoint = Optional.empty();
+        private Optional<String> introspectionEndpointAuthorization = 
Optional.empty();
+        private Optional<URL> userInfoEndpoint = Optional.empty();
+
+        private Builder() {
+        }
+
+        public Builder jwksURL(URL jwksURL) {
+            this.jwksURL = jwksURL;
+            return this;
+        }
+
+        public Builder claim(String claim) {
+            this.claim = claim;
+            return this;
+        }
+
+        public Builder oidcConfigurationURL(URL oidcConfigurationURL) {
+            this.oidcConfigurationURL = oidcConfigurationURL;
+            return this;
+        }
+
+        public Builder scope(String scope) {
+            this.scope = scope;
+            return this;
+        }
+
+        public Builder introspectionEndpoint(Optional<URL> 
introspectionEndpoint) {
+            this.introspectionEndpoint = introspectionEndpoint;
+            return this;
+        }
+
+        public Builder introspectionEndpoint(URL introspectionEndpoint) {
+            this.introspectionEndpoint = 
Optional.ofNullable(introspectionEndpoint);
+            return this;
+        }
+
+        public Builder introspectionEndpointAuthorization(Optional<String> 
introspectionEndpointAuthorization) {
+            this.introspectionEndpointAuthorization = 
introspectionEndpointAuthorization;
+            return this;
+        }
+
+        public Builder introspectionEndpointAuthorization(String 
introspectionEndpointAuthorization) {
+            this.introspectionEndpointAuthorization = 
Optional.ofNullable(introspectionEndpointAuthorization);
+            return this;
+        }
+
+        public Builder userInfoEndpoint(Optional<URL> userInfoEndpoint) {
+            this.userInfoEndpoint = userInfoEndpoint;
+            return this;
+        }
+
+        public Builder userInfoEndpoint(URL userInfoEndpoint) {
+            this.userInfoEndpoint = Optional.ofNullable(userInfoEndpoint);
+            return this;
+        }
+
+        public OidcSASLConfiguration build() {
+            Preconditions.checkNotNull(jwksURL, "jwksURL is mandatory");
+            Preconditions.checkNotNull(claim, "claim is mandatory");
+            Preconditions.checkNotNull(oidcConfigurationURL, 
"oidcConfigurationURL is mandatory");
+            Preconditions.checkNotNull(scope, "scope is mandatory");
+
+            return new OidcSASLConfiguration(jwksURL, claim, 
oidcConfigurationURL, scope,
+                introspectionEndpoint, introspectionEndpointAuthorization, 
userInfoEndpoint);
+        }
+    }
 
     public static OidcSASLConfiguration 
parse(HierarchicalConfiguration<ImmutableNode> configuration) throws 
MalformedURLException {
         String jwksURL = configuration.getString("jwksURL", null);
@@ -45,6 +129,14 @@ public class OidcSASLConfiguration {
         String introspectionUrl = configuration.getString("introspection.url", 
null);
         String userInfoUrl = configuration.getString("userinfo.url", null);
 
+        if (introspectionUrl == null) {
+            if (FORCE_INTROSPECT) {
+                throw new IllegalArgumentException("'introspection.url' is 
mandatory for secure set up. Disable this check with 
-Djames.sasl.oidc.force.introspect=false.");
+            } else {
+                LOGGER.warn("'introspection.url' is mandatory for secure set 
up. This check was disabled with -Djames.sasl.oidc.force.introspect=false.");
+            }
+        }
+
         return new OidcSASLConfiguration(new URL(jwksURL), claim, new 
URL(oidcConfigurationURL), scope, Optional.ofNullable(introspectionUrl)
             .map(Throwing.function(URL::new)), 
Optional.ofNullable(configuration.getString("introspection.auth", null)),
             Optional.ofNullable(userInfoUrl).map(Throwing.function(URL::new)));
@@ -58,7 +150,7 @@ public class OidcSASLConfiguration {
     private final Optional<String> introspectionEndpointAuthorization;
     private final Optional<URL> userInfoEndpoint;
 
-    public OidcSASLConfiguration(URL jwksURL,
+    private OidcSASLConfiguration(URL jwksURL,
                                  String claim,
                                  URL oidcConfigurationURL,
                                  String scope,
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 ff18fcf56a..03674929b8 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
@@ -70,38 +70,43 @@ class OidcJwtTokenVerifierTest {
 
     @Test
     void verifyAndClaimShouldReturnClaimValueWhenValidTokenHasKid() {
-        Optional<String> email_address = 
OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address");
+        Optional<String> emailAddress = new 
OidcJwtTokenVerifier(configForClaim("email_address")).verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN);
+
         SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(email_address.isPresent()).isTrue();
-            
softly.assertThat(email_address.get()).isEqualTo("[email protected]");
+            softly.assertThat(emailAddress.isPresent()).isTrue();
+            softly.assertThat(emailAddress.get()).isEqualTo("[email protected]");
         });
     }
 
     @Test
     void verifyAndClaimShouldReturnClaimValueWhenValidTokenHasNotKid() {
-        Optional<String> email_address = 
OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN_HAS_NOT_KID,
 getJwksURL(), "email_address");
+        Optional<String> emailAddress = new 
OidcJwtTokenVerifier(configForClaim("email_address")).verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN_HAS_NOT_KID);
+
         SoftAssertions.assertSoftly(softly -> {
-            softly.assertThat(email_address.isPresent()).isTrue();
-            
softly.assertThat(email_address.get()).isEqualTo("[email protected]");
+            softly.assertThat(emailAddress.isPresent()).isTrue();
+            softly.assertThat(emailAddress.get()).isEqualTo("[email protected]");
         });
     }
 
     @Test
     void verifyAndClaimShouldReturnEmptyWhenValidTokenHasNotFoundKid() {
-        
assertThat(OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN_HAS_NOT_FOUND_KID,
 getJwksURL(), "email_address"))
+        assertThat(new OidcJwtTokenVerifier(configForClaim("email_address"))
+            
.verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN_HAS_NOT_FOUND_KID))
             .isEmpty();
     }
 
     @Test
     void verifyAndClaimShouldReturnEmptyWhenClaimNameNotFound() {
-        
assertThat(OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "not_found"))
+        assertThat(new OidcJwtTokenVerifier(configForClaim("not_found"))
+            .verifySignatureAndExtractClaim(OidcTokenFixture.VALID_TOKEN))
             .isEmpty();
     }
 
 
     @Test
     void verifyAndClaimShouldReturnEmptyWhenInvalidToken() {
-        
assertThat(OidcJwtTokenVerifier.verifySignatureAndExtractClaim(OidcTokenFixture.INVALID_TOKEN,
 getJwksURL(), "email_address"))
+        assertThat(new OidcJwtTokenVerifier(configForClaim("email_address"))
+            .verifySignatureAndExtractClaim(OidcTokenFixture.INVALID_TOKEN))
             .isEmpty();
     }
 
@@ -111,7 +116,8 @@ class OidcJwtTokenVerifierTest {
             .when(HttpRequest.request().withPath(USERINFO_PATH))
             .respond(HttpResponse.response().withStatusCode(201));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getJwksURL(), "email_address", getUserInfoEndpoint()))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getUserInfoEndpoint()))
             .block())
             .isInstanceOf(UserInfoCheckException.class)
             .hasMessageContaining("Error when check token by userInfo");
@@ -125,7 +131,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody("badResponse1", StandardCharsets.UTF_8));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getJwksURL(), "email_address", getUserInfoEndpoint()))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getUserInfoEndpoint()))
             .block())
             .isInstanceOf(UserInfoCheckException.class)
             .hasMessageContaining("Error when check token by userInfo");
@@ -146,11 +153,25 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(userInfoResponse, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "preferred_username", getUserInfoEndpoint()))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("preferred_username"))
+                .verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getUserInfoEndpoint()))
             .block())
             .isNull();
     }
 
+    private OidcSASLConfiguration configForClaim(String claim) {
+        try {
+            return OidcSASLConfiguration.builder()
+                .jwksURL(getJwksURL())
+                .scope("email")
+                .oidcConfigurationURL(new URL("https://whatever.nte";))
+                .claim(claim)
+                .build();
+        } catch (MalformedURLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     @Test
     void verifyWithUserinfoShouldReturnClaimValueWhenPassCheckToken() {
         mockServer
@@ -159,7 +180,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(USERINFO_RESPONSE, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address", getUserInfoEndpoint()))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithUserinfo(OidcTokenFixture.VALID_TOKEN, 
getUserInfoEndpoint()))
             .block())
             .isEqualTo("[email protected]");
     }
@@ -172,7 +194,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(USERINFO_RESPONSE, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.INVALID_TOKEN,
 getJwksURL(), "email_address", getUserInfoEndpoint()))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithUserinfo(OidcTokenFixture.INVALID_TOKEN, 
getUserInfoEndpoint()))
             .block())
             .isNull();
     }
@@ -193,7 +216,7 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(userInfoResponse, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(OidcTokenFixture.INVALID_TOKEN,
 getJwksURL(), "preferred_username", getUserInfoEndpoint()))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("preferred_username")).verifyWithUserinfo(OidcTokenFixture.INVALID_TOKEN,
 getUserInfoEndpoint()))
             .block())
             .isNull();
     }
@@ -204,8 +227,8 @@ class OidcJwtTokenVerifierTest {
             .when(HttpRequest.request().withPath(INTROSPECTION_PATH))
             .respond(HttpResponse.response().withStatusCode(201));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address"
-                , new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                    .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isInstanceOf(TokenIntrospectionException.class)
             .hasMessageContaining("Error when introspecting token");
@@ -219,8 +242,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody("badResponse1", StandardCharsets.UTF_8));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isInstanceOf(TokenIntrospectionException.class)
             .hasMessageContaining("Error when introspecting token");
@@ -249,8 +272,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(introspectionResponse, StandardCharsets.UTF_8));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isInstanceOf(TokenIntrospectionException.class)
             .hasMessageContaining("Error when introspecting token");
@@ -280,8 +303,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(introspectionResponse, StandardCharsets.UTF_8));
 
-        assertThatThrownBy(() -> 
Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThatThrownBy(() -> Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isInstanceOf(TokenIntrospectionException.class)
             .hasMessageContaining("Error when introspecting token");
@@ -295,8 +318,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(INTROSPECTION_RESPONSE, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "email_address",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isEqualTo("[email protected]");
     }
@@ -317,8 +340,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(introspectionResponse, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "preferred_username",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("preferred_username"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isNull();
     }
@@ -339,8 +362,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(introspectionResponse, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN,
 getJwksURL(), "preferred_username",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("preferred_username"))
+                .verifyWithIntrospection(OidcTokenFixture.VALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isNull();
     }
@@ -353,8 +376,8 @@ class OidcJwtTokenVerifierTest {
                 .withHeader("Content-Type", "application/json")
                 .withBody(INTROSPECTION_RESPONSE, StandardCharsets.UTF_8));
 
-        
assertThat(Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(OidcTokenFixture.INVALID_TOKEN,
 getJwksURL(), "email_address",
-                new IntrospectionEndpoint(getIntrospectionEndpoint(), 
Optional.empty())))
+        assertThat(Mono.from(new 
OidcJwtTokenVerifier(configForClaim("email_address"))
+                .verifyWithIntrospection(OidcTokenFixture.INVALID_TOKEN, new 
IntrospectionEndpoint(getIntrospectionEndpoint(), Optional.empty())))
             .block())
             .isNull();
     }
diff --git a/server/protocols/protocols-imap4/pom.xml 
b/server/protocols/protocols-imap4/pom.xml
index 7dda6aa773..cdb72157bf 100644
--- a/server/protocols/protocols-imap4/pom.xml
+++ b/server/protocols/protocols-imap4/pom.xml
@@ -192,7 +192,7 @@
                     </systemPropertyVariables>
                     <argLine>-Djava.library.path=
                         
-javaagent:"${settings.localRepository}"/org/jacoco/org.jacoco.agent/${jacoco-maven-plugin.version}/org.jacoco.agent-${jacoco-maven-plugin.version}-runtime.jar=destfile=${basedir}/target/jacoco.exec
-                        -Xms512m -Xmx1024m</argLine>
+                        -Xms512m -Xmx1024m 
-Djames.sasl.oidc.force.introspect=false</argLine>
                     <reuseForks>true</reuseForks>
                     <!-- Fail tests longer than 20 minutes, prevent form 
random locking tests -->
                     
<forkedProcessTimeoutInSeconds>1200</forkedProcessTimeoutInSeconds>
diff --git 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
index 5ded55125b..5a4baf01ec 100644
--- 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
+++ 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
@@ -31,8 +31,8 @@ import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.decode.ImapDecoder;
 import org.apache.james.imap.encode.ImapEncoder;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.metrics.api.GaugeRegistry;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.protocols.netty.ChannelHandlerFactory;
diff --git 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index 6c8b228d10..23f9776a35 100644
--- 
a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ 
b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -35,8 +35,8 @@ import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.imap.encode.ImapResponseWriter;
 import org.apache.james.imap.message.Literal;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.netty.Encryption;
 import org.apache.james.protocols.netty.LineHandlerAware;
 
diff --git 
a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
 
b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
index fcf15a105e..9da0f671e4 100644
--- 
a/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
+++ 
b/server/protocols/protocols-lmtp/src/main/java/org/apache/james/lmtpserver/netty/LMTPServer.java
@@ -23,9 +23,9 @@ import java.util.Optional;
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.lmtpserver.CoreCmdHandlerLoader;
 import org.apache.james.lmtpserver.jmx.JMXHandlersLoader;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.api.ProtocolTransport;
 import org.apache.james.protocols.lib.handler.HandlersPackage;
diff --git a/server/protocols/protocols-smtp/pom.xml 
b/server/protocols/protocols-smtp/pom.xml
index 999d8a579a..49a4e2d46d 100644
--- a/server/protocols/protocols-smtp/pom.xml
+++ b/server/protocols/protocols-smtp/pom.xml
@@ -226,7 +226,7 @@
                     </systemPropertyVariables>
                     <argLine>-Djava.library.path=
                         
-javaagent:"${settings.localRepository}"/org/jacoco/org.jacoco.agent/${jacoco-maven-plugin.version}/org.jacoco.agent-${jacoco-maven-plugin.version}-runtime.jar=destfile=${basedir}/target/jacoco.exec
-                        -Xms512m -Xmx1024m</argLine>
+                        -Xms512m -Xmx1024m 
-Djames.sasl.oidc.force.introspect=false</argLine>
                     <reuseForks>true</reuseForks>
                     <!-- Fail tests longer than 20 minutes, prevent form 
random locking tests -->
                     
<forkedProcessTimeoutInSeconds>1200</forkedProcessTimeoutInSeconds>
diff --git 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/UsersRepositoryAuthHook.java
 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/UsersRepositoryAuthHook.java
index 7c16adf3d7..0af1611333 100644
--- 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/UsersRepositoryAuthHook.java
+++ 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/UsersRepositoryAuthHook.java
@@ -18,17 +18,14 @@
  ****************************************************************/
 package org.apache.james.smtpserver;
 
-import java.util.Optional;
-
 import javax.inject.Inject;
 
 import org.apache.james.core.Username;
 import org.apache.james.jwt.OidcJwtTokenVerifier;
-import org.apache.james.jwt.introspection.IntrospectionEndpoint;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.protocols.api.OIDCSASLParser;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.hook.AuthHook;
 import org.apache.james.protocols.smtp.hook.HookResult;
@@ -38,8 +35,6 @@ import org.apache.james.user.api.UsersRepositoryException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import reactor.core.publisher.Mono;
-
 /**
  * This Auth hook can be used to authenticate against the james user repository
  */
@@ -76,7 +71,7 @@ public class UsersRepositoryAuthHook implements AuthHook {
     @Override
     public HookResult doSasl(SMTPSession session, OidcSASLConfiguration 
configuration, String initialResponse) {
         return OIDCSASLParser.parse(initialResponse)
-            .flatMap(oidcInitialResponseValue -> validateToken(configuration, 
oidcInitialResponseValue.getToken())
+            .flatMap(oidcInitialResponseValue -> new 
OidcJwtTokenVerifier(configuration).validateToken(oidcInitialResponseValue.getToken())
                 .map(authenticatedUser -> {
                     Username associatedUser = 
Username.of(oidcInitialResponseValue.getAssociatedUser());
                     if (!associatedUser.equals(authenticatedUser)) {
@@ -114,35 +109,4 @@ public class UsersRepositoryAuthHook implements AuthHook {
             return HookResult.DECLINED;
         }
     }
-
-    private Optional<Username> validateToken(OidcSASLConfiguration 
oidcSASLConfiguration, String token) {
-        if (oidcSASLConfiguration.isCheckTokenByIntrospectionEndpoint()) {
-            return validTokenWithIntrospection(oidcSASLConfiguration, token);
-        } else if (oidcSASLConfiguration.isCheckTokenByUserinfoEndpoint()) {
-            return validTokenWithUserInfo(oidcSASLConfiguration, token);
-        } else {
-            return OidcJwtTokenVerifier.verifySignatureAndExtractClaim(token, 
oidcSASLConfiguration.getJwksURL(), oidcSASLConfiguration.getClaim())
-                .map(Username::of);
-        }
-    }
-
-    private Optional<Username> validTokenWithUserInfo(OidcSASLConfiguration 
oidcSASLConfiguration, String token) {
-        return Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(token,
-                oidcSASLConfiguration.getJwksURL(),
-                oidcSASLConfiguration.getClaim(),
-                oidcSASLConfiguration.getUserInfoEndpoint().orElseThrow()))
-            .blockOptional()
-            .map(Username::of);
-    }
-
-    private static Optional<Username> 
validTokenWithIntrospection(OidcSASLConfiguration oidcSASLConfiguration, String 
token) {
-        return Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(token,
-                oidcSASLConfiguration.getJwksURL(),
-                oidcSASLConfiguration.getClaim(),
-                oidcSASLConfiguration.getIntrospectionEndpoint()
-                    .map(endpoint -> new IntrospectionEndpoint(endpoint, 
oidcSASLConfiguration.getIntrospectionEndpointAuthorization()))
-                    .orElseThrow()))
-            .blockOptional()
-            .map(Username::of);
-    }
 }
diff --git 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
index 93c5902ddb..6e9051bea4 100644
--- 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
+++ 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/netty/SMTPServer.java
@@ -32,7 +32,7 @@ import 
org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.dnsservice.library.netmatcher.NetMatcher;
-import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.jwt.OidcSASLConfiguration;
 import org.apache.james.protocols.api.ProtocolSession;
 import org.apache.james.protocols.api.ProtocolTransport;
 import org.apache.james.protocols.lib.handler.HandlersPackage;


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


Reply via email to