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

jgallimore pushed a commit to branch tomee-9.x
in repository https://gitbox.apache.org/repos/asf/tomee.git

commit 8414084c93193767bea7b81783de53a7be866e08
Author: Zoltán Tichov <zoltan.tic...@gmail.com>
AuthorDate: Sun Dec 18 12:37:48 2022 +0100

    Implement tomee.mp.jwt.allow.no-exp property over mp.jwt.tomee.allow.no-exp
---
 docs/microprofile/jwt.adoc                         |   3 +-
 .../jwt/itest/AllowNoExpPropertyTest.java          | 253 +++++++++++++++++++++
 .../jwt/config/JWTAuthConfigurationProperties.java |  15 +-
 3 files changed, 268 insertions(+), 3 deletions(-)

diff --git a/docs/microprofile/jwt.adoc b/docs/microprofile/jwt.adoc
index 270be03e6e..d1b2e948e0 100644
--- a/docs/microprofile/jwt.adoc
+++ b/docs/microprofile/jwt.adoc
@@ -81,7 +81,8 @@ In addition to the standard MicroProfile JWT configuration 
properties above, the
 | Property
 | Type
 | Description
-| `mp.jwt.tomee.allow.no-exp`
+| `mp.jwt.tomee.allow.no-exp` is deprecated please use 
`tomee.mp.jwt.allow.no-exp` property instead
+| `tomee.mp.jwt.allow.no-exp`
 | Boolean
 | Disables enforcing the `exp` time of the JWT.  Useful if JWTs are also 
verified by an API Gateway or proxy before reaching the server.  The default 
value is `false`
 | `tomee.jwt.verify.publickey.cache`
diff --git 
a/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/AllowNoExpPropertyTest.java
 
b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/AllowNoExpPropertyTest.java
new file mode 100644
index 0000000000..467cc17a6d
--- /dev/null
+++ 
b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/AllowNoExpPropertyTest.java
@@ -0,0 +1,253 @@
+/*
+ * 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.tomee.microprofile.jwt.itest;
+
+import jakarta.annotation.security.RolesAllowed;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Base64;
+import static java.util.Collections.singletonList;
+import java.util.Optional;
+import org.apache.cxf.feature.LoggingFeature;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.johnzon.jaxrs.JohnzonProvider;
+import org.apache.tomee.server.composer.Archive;
+import org.apache.tomee.server.composer.TomEE;
+import org.eclipse.microprofile.auth.LoginConfig;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+
+public class AllowNoExpPropertyTest {
+   
+    @Test
+    public void testNewPropertyOverridesOld1() throws Exception {
+        final Tokens tokens = Tokens.rsa(2048, 256);
+        final File appJar = Archive.archive()
+                .add(AllowNoExpPropertyTest.class)
+                .add(ColorService.class)
+                .add(Api.class)
+                .add("META-INF/microprofile-config.properties", "#\n" +
+                        "mp.jwt.verify.publickey=" + 
Base64.getEncoder().encodeToString(tokens.getPublicKey().getEncoded())
+                         + "\n" + "mp.jwt.tomee.allow.no-exp=false"
+                         + "\n" + "tomee.mp.jwt.allow.no-exp=true")
+                .asJar();
+
+        final ArrayList<String> output = new ArrayList<>();
+        final TomEE tomee = TomEE.microprofile()
+                .add("webapps/test/WEB-INF/beans.xml", "")
+                .add("webapps/test/WEB-INF/lib/app.jar", appJar)
+                .watch("org.apache.tomee.microprofile.jwt.", "\n", output::add)
+                .build();
+
+        final WebClient webClient = 
createWebClient(tomee.toURI().resolve("/test").toURL());
+
+        final String claims = "{" +
+                "  \"sub\":\"Jane Awesome\"" +
+                "}";
+
+        {// invalid token
+            final String token = tokens.asToken(claims);
+            final Response response = webClient.reset()
+                    .path("/movies")
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", "Bearer " + token)
+                    .get();
+            assertEquals(403, response.getStatus());
+        }
+
+        assertPresent(output , "mp.jwt.tomee.allow.no-exp property is 
deprecated");
+        assertNotPresent(output, "rejected due to invalid claims");
+        assertNotPresent(output, "No Expiration Time (exp) claim present.");
+        assertNotPresent(output, "\tat org."); // no stack traces
+    }
+
+    @Test
+    public void testNewPropertyOverridesOld2() throws Exception {
+        final Tokens tokens = Tokens.rsa(2048, 256);
+        final File appJar = Archive.archive()
+                .add(AllowNoExpPropertyTest.class)
+                .add(ColorService.class)
+                .add(Api.class)
+                .add("META-INF/microprofile-config.properties", "#\n" +
+                        "mp.jwt.verify.publickey=" + 
Base64.getEncoder().encodeToString(tokens.getPublicKey().getEncoded())
+                         + "\n" + "mp.jwt.tomee.allow.no-exp=true"
+                         + "\n" + "tomee.mp.jwt.allow.no-exp=false")
+                .asJar();
+
+        final ArrayList<String> output = new ArrayList<>();
+        final TomEE tomee = TomEE.microprofile()
+                .add("webapps/test/WEB-INF/beans.xml", "")
+                .add("webapps/test/WEB-INF/lib/app.jar", appJar)
+                .watch("org.apache.tomee.microprofile.jwt.", "\n", output::add)
+                .build();
+
+        final WebClient webClient = 
createWebClient(tomee.toURI().resolve("/test").toURL());
+
+        final String claims = "{" +
+                "  \"sub\":\"Jane Awesome\"" +
+                "}";
+
+        {// invalid token
+            final String token = tokens.asToken(claims);
+            final Response response = webClient.reset()
+                    .path("/movies")
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", "Bearer " + token)
+                    .get();
+            assertEquals(401, response.getStatus());
+        }
+
+        assertPresent(output , "mp.jwt.tomee.allow.no-exp property is 
deprecated");
+        assertPresent(output, "rejected due to invalid claims");
+        assertPresent(output, "No Expiration Time (exp) claim present.");
+        assertNotPresent(output, "\tat org."); // no stack traces
+    }
+    
+    @Test
+    public void testNewProperty() throws Exception {
+        final Tokens tokens = Tokens.rsa(2048, 256);
+        final File appJar = Archive.archive()
+                .add(AllowNoExpPropertyTest.class)
+                .add(ColorService.class)
+                .add(Api.class)
+                .add("META-INF/microprofile-config.properties", "#\n" +
+                        "mp.jwt.verify.publickey=" + 
Base64.getEncoder().encodeToString(tokens.getPublicKey().getEncoded())
+                         + "\n" + "tomee.mp.jwt.allow.no-exp=true")
+                .asJar();
+
+        final ArrayList<String> output = new ArrayList<>();
+        final TomEE tomee = TomEE.microprofile()
+                .add("webapps/test/WEB-INF/beans.xml", "")
+                .add("webapps/test/WEB-INF/lib/app.jar", appJar)
+                .watch("org.apache.tomee.microprofile.jwt.", "\n", output::add)
+                .build();
+
+        final WebClient webClient = 
createWebClient(tomee.toURI().resolve("/test").toURL());
+
+        final String claims = "{" +
+                "  \"sub\":\"Jane Awesome\"" +
+                "}";
+
+        {// invalid token
+            final String token = tokens.asToken(claims);
+            final Response response = webClient.reset()
+                    .path("/movies")
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", "Bearer " + token)
+                    .get();
+            assertEquals(403, response.getStatus());
+        }
+
+        assertNotPresent(output , "mp.jwt.tomee.allow.no-exp property is 
deprecated");
+        assertNotPresent(output, "rejected due to invalid claims");
+        assertNotPresent(output, "No Expiration Time (exp) claim present.");
+        assertNotPresent(output, "\tat org."); // no stack traces
+    }
+    
+    @Test
+    public void testOldProperty() throws Exception {
+        final Tokens tokens = Tokens.rsa(2048, 256);
+        final File appJar = Archive.archive()
+                .add(AllowNoExpPropertyTest.class)
+                .add(ColorService.class)
+                .add(Api.class)
+                .add("META-INF/microprofile-config.properties", "#\n" +
+                        "mp.jwt.verify.publickey=" + 
Base64.getEncoder().encodeToString(tokens.getPublicKey().getEncoded())
+                         + "\n" + "mp.jwt.tomee.allow.no-exp=true")
+                .asJar();
+
+        final ArrayList<String> output = new ArrayList<>();
+        final TomEE tomee = TomEE.microprofile()
+                .add("webapps/test/WEB-INF/beans.xml", "")
+                .add("webapps/test/WEB-INF/lib/app.jar", appJar)
+                .watch("org.apache.tomee.microprofile.jwt.", "\n", output::add)
+                .build();
+
+        final WebClient webClient = 
createWebClient(tomee.toURI().resolve("/test").toURL());
+
+        final String claims = "{" +
+                "  \"sub\":\"Jane Awesome\"" +
+                "}";
+
+        {// invalid token
+            final String token = tokens.asToken(claims);
+            final Response response = webClient.reset()
+                    .path("/movies")
+                    .header("Content-Type", "application/json")
+                    .header("Authorization", "Bearer " + token)
+                    .get();
+            assertEquals(403, response.getStatus());
+        }
+
+        assertPresent(output , "mp.jwt.tomee.allow.no-exp property is 
deprecated");
+        assertNotPresent(output, "rejected due to invalid claims");
+        assertNotPresent(output, "No Expiration Time (exp) claim present.");
+        assertNotPresent(output, "\tat org."); // no stack traces
+    }
+    
+    public void assertPresent(final ArrayList<String> output, final String s) {
+        final Optional<String> actual = output.stream()
+                .filter(line -> line.contains(s))
+                .findFirst();
+
+        assertTrue(actual.isPresent());
+    }
+    public void assertNotPresent(final ArrayList<String> output, final String 
s) {
+        final Optional<String> actual = output.stream()
+                .filter(line -> line.contains(s))
+                .findFirst();
+
+        assertTrue(!actual.isPresent());
+    }
+
+    private static WebClient createWebClient(final URL base) {
+        return WebClient.create(base.toExternalForm(), singletonList(new 
JohnzonProvider<>()),
+                singletonList(new LoggingFeature()), null);
+    }
+
+    @ApplicationPath("/api")
+    @LoginConfig(authMethod = "MP-JWT")
+    public class Api extends Application {
+    }
+
+    @Path("/movies")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    @RequestScoped
+    public static class ColorService {
+
+        @GET
+        @RolesAllowed({"manager", "user"})
+        public String getAllMovies() {
+            return "Green";
+        }
+    }
+
+}
diff --git 
a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java
 
b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java
index e2f4823eef..65fac63995 100644
--- 
a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java
+++ 
b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java
@@ -38,6 +38,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Supplier;
 
 import static org.eclipse.microprofile.jwt.config.Names.AUDIENCES;
@@ -59,6 +60,7 @@ import static 
org.eclipse.microprofile.jwt.config.Names.VERIFIER_PUBLIC_KEY_LOCA
 public class JWTAuthConfigurationProperties {
     public static final String PUBLIC_KEY_ERROR = "Could not read MicroProfile 
Public Key";
     public static final String PUBLIC_KEY_ERROR_LOCATION = PUBLIC_KEY_ERROR + 
" from Location: ";
+    private static final Logger CONFIGURATION = 
Logger.getInstance(JWTLogCategories.CONFIG, 
JWTAuthConfigurationProperties.class);
 
     private Config config;
     private JWTAuthConfiguration jwtAuthConfiguration;
@@ -104,8 +106,8 @@ public class JWTAuthConfigurationProperties {
         final Supplier<Map<String, Key>> publicKeys = 
Keys.VERIFY.configure(config);
         final Supplier<Map<String, Key>> decryptKeys = 
Keys.DECRYPT.configure(config);
 
-        final Boolean allowNoExp = 
config.getOptionalValue("mp.jwt.tomee.allow.no-exp", 
Boolean.class).orElse(false);
-
+        final Boolean allowNoExp = queryAllowExp();
+        
         return new JWTAuthConfiguration(
                 publicKeys,
                 getIssuer().orElse(null),
@@ -117,6 +119,15 @@ public class JWTAuthConfigurationProperties {
                 config.getOptionalValue("mp.jwt.decrypt.key.algorithm", 
String.class).orElse(null),
                 config.getOptionalValue("mp.jwt.verify.publickey.algorithm", 
String.class).orElse(null));
     }
+    
+    private Boolean queryAllowExp(){
+        AtomicBoolean result = new AtomicBoolean(false);
+        config.getOptionalValue("mp.jwt.tomee.allow.no-exp", 
Boolean.class).ifPresent(value -> {
+            result.set(value);
+            CONFIGURATION.warning("mp.jwt.tomee.allow.no-exp property is 
deprecated, use tomee.mp.jwt.allow.no-exp propert instead.");
+            });
+        return config.getOptionalValue("tomee.mp.jwt.allow.no-exp", 
Boolean.class).orElse(result.get());
+    }
 
     enum Keys {
         VERIFY("mp.jwt.verify.publickey", "tomee.jwt.verify.publickey"),

Reply via email to