This is an automated email from the ASF dual-hosted git repository. dblevins pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/main by this push: new 0e090e6ac9 Explicitly test all MP-JWT key formats 0e090e6ac9 is described below commit 0e090e6ac9be1ec66bd3a9c086e90b403a4df489 Author: David Blevins <dblev...@tomitribe.com> AuthorDate: Fri Aug 26 14:26:02 2022 -0700 Explicitly test all MP-JWT key formats --- itests/microprofile-jwt-itests/pom.xml | 7 +- .../jwt/itest/PublicKeyFormatsTest.java | 168 +++++++++++++++++++++ .../tomee/microprofile/jwt/itest/Tokens.java | 13 ++ 3 files changed, 187 insertions(+), 1 deletion(-) diff --git a/itests/microprofile-jwt-itests/pom.xml b/itests/microprofile-jwt-itests/pom.xml index c4a1d98453..bcd12e47db 100644 --- a/itests/microprofile-jwt-itests/pom.xml +++ b/itests/microprofile-jwt-itests/pom.xml @@ -88,7 +88,12 @@ <version>${tomee.version}</version> <scope>test</scope> </dependency> - + <dependency> + <groupId>io.churchkey</groupId> + <artifactId>churchkey</artifactId> + <version>1.21</version> + <scope>test</scope> + </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> diff --git a/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/PublicKeyFormatsTest.java b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/PublicKeyFormatsTest.java new file mode 100644 index 0000000000..32aabb095d --- /dev/null +++ b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/PublicKeyFormatsTest.java @@ -0,0 +1,168 @@ +/* + * 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 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 org.junit.Ignore; +import org.junit.Test; + +import java.io.File; +import java.net.URL; + +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; + +public class PublicKeyFormatsTest { + + @Test + public void pkcs8Pem() throws Exception { + final Tokens tokens = Tokens.rsa(2048, 256); + + final File appJar = Archive.archive() + .add(PublicKeyFormatsTest.class) + .add(ColorService.class) + .add(Api.class) + .add("orange.pem", "-----BEGIN PUBLIC KEY-----\n" + + tokens.getEncodedPublicKey() + + "\n-----END PUBLIC KEY-----") + .add("META-INF/microprofile-config.properties", "#\n" + + "mp.jwt.verify.publickey.location=orange.pem") + .asJar(); + + final TomEE tomee = TomEE.microprofile() + .add("webapps/test/WEB-INF/beans.xml", "") + .add("webapps/test/WEB-INF/lib/app.jar", appJar) + .build(); + + assertVerification(tokens, tomee); + } + + @Test + public void jwk() throws Exception { + final Tokens tokens = Tokens.rsa(2048, 256); + + final File appJar = Archive.archive() + .add(PublicKeyFormatsTest.class) + .add(ColorService.class) + .add(Api.class) + .add("orange", tokens.getJwkPublicKey()) + .add("META-INF/microprofile-config.properties", "#\n" + + "mp.jwt.verify.publickey.location=orange") + .asJar(); + + final TomEE tomee = TomEE.microprofile() + .add("webapps/test/WEB-INF/beans.xml", "") + .add("webapps/test/WEB-INF/lib/app.jar", appJar) + .build(); + + assertVerification(tokens, tomee); + } + + @Test + public void jwks() throws Exception { + final Tokens tokens = Tokens.rsa(2048, 256); + + final File appJar = Archive.archive() + .add(PublicKeyFormatsTest.class) + .add(ColorService.class) + .add(Api.class) + .add("orange", tokens.getJwksPublicKey()) + .add("META-INF/microprofile-config.properties", "#\n" + + "mp.jwt.verify.publickey.location=orange") + .asJar(); + + final TomEE tomee = TomEE.microprofile() + .add("webapps/test/WEB-INF/beans.xml", "") + .add("webapps/test/WEB-INF/lib/app.jar", appJar) + .build(); + + assertVerification(tokens, tomee); + } + + private void assertVerification(final Tokens tokens, final TomEE tomee) throws Exception { + final WebClient webClient = createWebClient(tomee.toURI().resolve("/test").toURL()); + + final String claims = "{" + + " \"sub\":\"Jane Awesome\"," + + " \"iss\":\"https://server.example.com\"," + + " \"groups\":[\"manager\",\"user\"]," + + " \"jti\":\"uB3r7zOr\"," + + " \"exp\":2552047942" + + "}"; + + {// valid 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(200, response.getStatus()); + } + + {// invalid token + final String token = tokens.asToken(claims) + "a"; + final Response response = webClient.reset() + .path("/movies") + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + token) + .get(); + assertEquals(401, response.getStatus()); + } + } + + 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"; + } + } + +} \ No newline at end of file diff --git a/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/Tokens.java b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/Tokens.java index 52e5805bb5..0efba971ab 100644 --- a/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/Tokens.java +++ b/itests/microprofile-jwt-itests/src/test/java/org/apache/tomee/microprofile/jwt/itest/Tokens.java @@ -23,6 +23,7 @@ import com.nimbusds.jose.Requirement; import com.nimbusds.jose.crypto.RSASSASigner; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import io.churchkey.Keys; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -69,6 +70,18 @@ public class Tokens { return Base64.getEncoder().encodeToString(publicKey.getEncoded()); } + public String getJwkPublicKey() { + return Keys.of(publicKey).toJwk(); + } + + public String getJwksPublicKey() { + return Keys.of(publicKey).toJwks(); + } + + public String getPemPublicKey() { + return Keys.of(publicKey).toPem(); + } + public String asToken(final String claims) throws Exception { try { final JWSHeader header = new JWSHeader.Builder(new JWSAlgorithm("RS" + hashSize, Requirement.OPTIONAL))