You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by GitBox <gi...@apache.org> on 2022/05/18 11:21:14 UTC

[GitHub] [james-project] vttranlina opened a new pull request, #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

vttranlina opened a new pull request, #1006:
URL: https://github.com/apache/james-project/pull/1006

   Jira: https://issues.apache.org/jira/browse/JAMES-3755


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1133913503

   Related...
   
   ```
   
   
    
   --
     | Test Result (6 failures  / +6)org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenResponseMissingActivePropertyorg.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldSuccessWhenValidRequestorg.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenCanNotDeserializeResponseorg.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenNotAuthorizedorg.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldPostValidRequestorg.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldReturnUpdatedResponse
   
   [Test Result](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/) (6 failures / +6)
   
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenResponseMissingActiveProperty](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldFailWhenResponseMissingActiveProperty/)
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldSuccessWhenValidRequest](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldSuccessWhenValidRequest/)
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenCanNotDeserializeResponse](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldFailWhenCanNotDeserializeResponse/)
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldFailWhenNotAuthorized](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldFailWhenNotAuthorized/)
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldPostValidRequest](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldPostValidRequest/)
       [org.apache.james.jwt.introspection.DefaultIntrospectionClientTest.introspectShouldReturnUpdatedResponse](https://ci-builds.apache.org/job/james/job/ApacheJames/job/PR-1006/5/testReport/junit/org.apache.james.jwt.introspection/DefaultIntrospectionClientTest/introspectShouldReturnUpdatedResponse/)
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] quantranhong1999 commented on a diff in pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
quantranhong1999 commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r878989027


##########
server/protocols/jwt/src/test/java/org/apache/james/jwt/introspection/DefaultIntrospectionClientTest.java:
##########
@@ -0,0 +1,213 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.SoftAssertions.assertSoftly;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.HttpRequest;
+import org.mockserver.model.HttpResponse;
+import org.mockserver.verify.VerificationTimes;
+
+import reactor.core.publisher.Mono;
+
+public class DefaultIntrospectionClientTest {
+    private static final String INTROSPECTION_TOKEN_URI_PATH = "/token/introspect";
+
+    private ClientAndServer mockServer;
+
+    @BeforeEach
+    public void setUp() {
+        mockServer = ClientAndServer.startClientAndServer(0);
+    }
+
+    @AfterEach
+    void tearDown() {
+        mockServer.stop();
+    }
+
+    private IntrospectionEndpoint getIntrospectionTokenEndpoint() {
+        try {
+            return new IntrospectionEndpoint(new URL(String.format("http://abc:xyz@127.0.0.1:%s%s", mockServer.getLocalPort(), INTROSPECTION_TOKEN_URI_PATH)),

Review Comment:
   ```suggestion
               return new IntrospectionEndpoint(new URL(String.format("http://127.0.0.1:%s%s", mockServer.getLocalPort(), INTROSPECTION_TOKEN_URI_PATH)),
   ```
   
   This should solve the failing tests.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r878010988


##########
src/site/xdoc/server/config-smtp-lmtp.xml:
##########
@@ -115,6 +115,8 @@
         <dd>Optional. An OAuth introspection token URL will be called to validate the token (RF: RFC7662).
             Only configure this when you want to validate the revocation token by the OIDC provider.
             Note that James always verifies the signature of the token even whether this configuration is provided or not.</dd>
+        <dt><strong>auth.oidc.introspection.auth</strong></dt>
+        <dd>Optional. Provide Authorization in header request when introspecting token.</dd>

Review Comment:
   Provide an example IMO:
   
   ```suggestion
           <dd>Optional. Provide Authorization in header request when introspecting token. Eg: `Basic xyz`</dd>
   ```



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionEndpoint.java:
##########
@@ -0,0 +1,60 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.URL;
+import java.util.Objects;
+import java.util.Optional;
+
+public class IntrospectionEndpoint {
+    private final URL url;
+    private final Optional<String> authorizationHeader;
+
+    public IntrospectionEndpoint(URL url, Optional<String> authorizationHeader) {
+        this.url = url;
+        this.authorizationHeader = authorizationHeader;
+    }
+
+    public URL getUrl() {
+        return url;
+    }
+
+    public Optional<String> getAuthorizationHeader() {
+        return authorizationHeader;
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof IntrospectionEndpoint) {
+            IntrospectionEndpoint that = (IntrospectionEndpoint) o;
+
+            return Objects.equals(this.url, that.url)
+                &&
+                Objects.equals(this.authorizationHeader, that.authorizationHeader)
+                ;

Review Comment:
   ```suggestion
               return Objects.equals(this.url, that.url)
                   &&Objects.equals(this.authorizationHeader, that.authorizationHeader);
   ```



##########
server/apps/distributed-app/docs/modules/ROOT/pages/configure/smtp.adoc:
##########
@@ -108,6 +108,9 @@ can be used to enforce strong authentication mechanisms.
 Only configure this when you want to validate the revocation token by the OIDC provider.
 Note that James always verifies the signature of the token even whether this configuration is provided or not.
 
+| auth.oidc.introspection.auth
+| Optional. Provide Authorization in header request when introspecting token.

Review Comment:
   Provide an example IMO
   :
   ```suggestion
   | Optional. Provide Authorization in header request when introspecting token.
   Eg: `Basic xyz`
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876651716


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));

Review Comment:
   Map<String, String> is a Map<String, Object> ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa merged pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa merged PR #1006:
URL: https://github.com/apache/james-project/pull/1006


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876651904


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));
+        }
+
+        private final URL endpoint;
+        private final Map<String, Object> formAttributes;
+        private final Map<String, Object> headerAttributes;

Review Comment:
   token_type_hint is optional no?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876529358


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));

Review Comment:
   I want to convert Map<String, String> to Map<String, Object>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876652533


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));
+        }
+
+        private final URL endpoint;
+        private final Map<String, Object> formAttributes;
+        private final Map<String, Object> headerAttributes;

Review Comment:
   > IMO, headerAttributes will make it more generic, if just only basic auth, we don't even need an Authorization header, we can bypass it by inline URL. (http://user:pass@domain_token_introspect/)
   
   If it works it could be nice ;-)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1131498930

   TODO 
   
   - [ ] Document
   - [ ] Record video demo with thunderbird + oidc keycloak


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876532003


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));
+        }
+
+        private final URL endpoint;
+        private final Map<String, Object> formAttributes;
+        private final Map<String, Object> headerAttributes;

Review Comment:
   > I think form attributes should be supplied according to the payload introspected thus should not be in the configuration.
   
   Example for keycloak. It support `token_type_hint` form. IMO, it will support similar cases
   
   > Do we want arbitrary header configuration or are we just interested in Authorization ?
   
   IMO, `headerAttributes` will make it more generic, if just only basic auth, we don't even need an Authorization header, we can bypass it by inline URL. (http://user:pass@domain_token_introspect)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on a diff in pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r877961651


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/DefaultIntrospectionClient.java:
##########
@@ -0,0 +1,76 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class DefaultIntrospectionClient implements IntrospectionClient {
+
+    public static final String TOKEN_ATTRIBUTE = "token";
+    private final HttpClient httpClient;
+    private final ObjectMapper deserializer;
+
+    public DefaultIntrospectionClient() {
+        this.httpClient = HttpClient.create(ConnectionProvider.builder(this.getClass().getName())
+                .build())
+            .disableRetry(true)
+            .headers(builder -> {
+                builder.add("Accept", "application/json");
+                builder.add("Content-Type", "application/x-www-form-urlencoded");
+            });
+        this.deserializer = new ObjectMapper();
+    }
+
+    @Override
+    public Publisher<TokenIntrospectionResponse> introspect(URL introspectURL, String token) {
+        return httpClient.post()
+            .uri(introspectURL.toString())

Review Comment:
   Netty httpclient doesn't accept the user+pass inline URL. 
   (ex: http://user:pass@domain.org)
   It throws `java.net.UnknownHostException`.
   Maybe we need Authorization property
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1133001533

   Cool video!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] quantranhong1999 commented on a diff in pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
quantranhong1999 commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r877744038


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/OidcJwtTokenVerifier.java:
##########
@@ -55,4 +60,24 @@ public static <T> Optional<T> getClaimWithoutSignatureVerification(String token,
             return Optional.empty();
         }
     }
+
+    private final Optional<IntrospectionClient> introspectionClient;
+
+    public OidcJwtTokenVerifier(Optional<IntrospectionClient> introspectionClient) {
+        this.introspectionClient = introspectionClient;
+    }
+
+    public Publisher<String> verify(String jwtToken, URL jwksURL, String claimName) {

Review Comment:
   Can we have a better name for this? Maybe `verifyWithMaybeIntrospection` ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1132784886

   
   https://user-images.githubusercontent.com/81145350/169517425-e31dbac3-11e7-412d-a91f-34641e58f68a.mp4
   
   Video demo with thunderbird + oidc keycloak


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1132784438

   Video demo with thunderbird + oidc keycloak
   https://user-images.githubusercontent.com/81145350/169517314-9d0f7454-5e49-46ec-9bb8-4d5078eec650.mp4
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] vttranlina commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
vttranlina commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876871511


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));
+        }
+
+        private final URL endpoint;
+        private final Map<String, Object> formAttributes;
+        private final Map<String, Object> headerAttributes;

Review Comment:
   Yes, I tested it with the postman, and it works!
   I removed `formAttributes` , `headerAttributes` to make it simpler



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: [WIP] JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876508898


##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);

Review Comment:
   `introspection.url` ?



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {

Review Comment:
   DefaultIntrospectionClient ?



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))

Review Comment:
   `introspection.authorization` ?



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)

Review Comment:
   Awesome! I was not aware of this method! It would make life much, much easier!



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));

Review Comment:
   Why do we need to stream map entries to collect them again to a map?



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/TokenIntrospectionResponse.java:
##########
@@ -0,0 +1,60 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.util.Optional;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.BooleanNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import com.google.common.base.Preconditions;
+
+public class TokenIntrospectionResponse {
+    public static TokenIntrospectionResponse parse(JsonNode json) {
+        return new TokenIntrospectionResponse(json);
+    }
+
+    private final boolean active;
+    private final Optional<String> scope;

Review Comment:
   We should add support for other properties
   
   https://datatracker.ietf.org/doc/html/rfc7662#section-2.2



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClientDefault.java:
##########
@@ -0,0 +1,138 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.reactivestreams.Publisher;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import reactor.core.publisher.Mono;
+import reactor.netty.ByteBufMono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+
+public class IntrospectionClientDefault implements IntrospectionClient {
+
+    public static class TokenIntrospectionConfiguration {
+
+        public static TokenIntrospectionConfiguration parse(HierarchicalConfiguration<ImmutableNode> configuration) throws MalformedURLException {
+            String introspectionTokenEndpoint = configuration.getString("introspectionTokenEndpoint", null);
+            Preconditions.checkNotNull(introspectionTokenEndpoint, "`introspectionTokenEndpoint` property need to be specified inside the oidc tag");
+            URL introspectionTokenEndpointURL = new URL(introspectionTokenEndpoint);
+            Map<String, Object> formAttributes = Optional.ofNullable(configuration.getString("introspectionTokenFormAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            Map<String, Object> headerAttributes = Optional.ofNullable(configuration.getString("introspectionTokenHeaderAttrs", null))
+                .map(TokenIntrospectionConfiguration::parseStringToMap)
+                .orElse(Map.of());
+
+            return new TokenIntrospectionConfiguration(introspectionTokenEndpointURL, formAttributes, headerAttributes);
+        }
+
+        private static Map<String, Object> parseStringToMap(String value) {
+            return Splitter.on(",").withKeyValueSeparator("=").split(value)
+                .entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue()));
+        }
+
+        private final URL endpoint;
+        private final Map<String, Object> formAttributes;
+        private final Map<String, Object> headerAttributes;

Review Comment:
   I think form attributes should be supplied according to the payload introspected thus should not be in the configuration.
   
   Do we want arbitrary header configuration or are we just interested in `Authorization` ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] Arsnael commented on pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
Arsnael commented on PR #1006:
URL: https://github.com/apache/james-project/pull/1006#issuecomment-1132555080

   Read it, nothing to add.
   
   I thought about doc but it seems you put it a bit above in a todo so I guess you have it in mind :)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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


[GitHub] [james-project] chibenwa commented on a diff in pull request #1006: JAMES-3755 IMAP/SMTP OIDC token introspection

Posted by GitBox <gi...@apache.org>.
chibenwa commented on code in PR #1006:
URL: https://github.com/apache/james-project/pull/1006#discussion_r876881191


##########
protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java:
##########
@@ -184,14 +188,20 @@ private void doOAuth(String initialResponse, ImapSession session, ImapRequest re
         } else {
             OIDCSASLParser.parse(initialResponse)
                 .flatMap(oidcInitialResponseValue -> session.oidcSaslConfiguration()
-                    .flatMap(configuration -> new OidcJwtTokenVerifier().verifyAndExtractClaim(oidcInitialResponseValue.getToken(), configuration.getJwksURL(), configuration.getClaim())))
-                .flatMap(this::extractUserFromClaim)
+                    .flatMap(configure -> validateToken(configure, oidcInitialResponseValue.getToken())))
                 .ifPresentOrElse(username -> authSuccess(username, session, request, responder),
                     () -> manageFailureCount(session, request, responder, HumanReadableText.AUTHENTICATION_FAILED));
         }
         session.stopDetectingCommandInjection();
     }
 
+    private Optional<Username> validateToken(OidcSASLConfiguration oidcSASLConfiguration, String token) {
+        return Mono.just(new OidcJwtTokenVerifier(oidcSASLConfiguration.getIntrospectionEndpoint().map(DefaultIntrospectionClient::new)))

Review Comment:
   The introspection client should be a field, injected. The URL should likely be a part of the method.



##########
server/protocols/jwt/src/main/java/org/apache/james/jwt/introspection/IntrospectionClient.java:
##########
@@ -0,0 +1,28 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jwt.introspection;
+import org.reactivestreams.Publisher;
+
+public interface IntrospectionClient {
+
+    Publisher<TokenIntrospectionResponse> introspect(String token);

Review Comment:
   ```suggestion
       Publisher<TokenIntrospectionResponse> introspect(URL url, String token);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


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