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 cbeebe6478 TOMEE-4043 Remove support for JWTAuthConfiguration API cbeebe6478 is described below commit cbeebe6478933582d97e0b495e82f07279787d74 Author: David Blevins <dblev...@tomitribe.com> AuthorDate: Tue Sep 13 09:09:33 2022 -0700 TOMEE-4043 Remove support for JWTAuthConfiguration API --- examples/mp-rest-jwt/README.adoc | 329 --------------------- examples/mp-rest-jwt/README_es.adoc | 328 -------------------- examples/mp-rest-jwt/README_pt.adoc | 318 -------------------- examples/mp-rest-jwt/pom.xml | 199 ------------- .../src/main/java/org/superbiz/moviefun/Movie.java | 70 ----- .../java/org/superbiz/moviefun/MoviesBean.java | 61 ---- .../superbiz/moviefun/rest/ApplicationConfig.java | 28 -- .../rest/MoviesMPJWTConfigurationProvider.java | 56 ---- .../org/superbiz/moviefun/rest/MoviesRest.java | 77 ----- .../java/org/superbiz/moviefun/MoviesTest.java | 132 --------- .../java/org/superbiz/moviefun/TokenUtils.java | 257 ---------------- .../test/resources/META-INF/application-client.xml | 19 -- .../mp-rest-jwt/src/test/resources/Token1.json | 17 -- .../mp-rest-jwt/src/test/resources/Token2.json | 14 - .../mp-rest-jwt/src/test/resources/arquillian.xml | 32 -- .../mp-rest-jwt/src/test/resources/privateKey.pem | 28 -- .../mp-rest-jwt/src/test/resources/publicKey.pem | 9 - examples/pom.xml | 1 - 18 files changed, 1975 deletions(-) diff --git a/examples/mp-rest-jwt/README.adoc b/examples/mp-rest-jwt/README.adoc deleted file mode 100644 index 231ef6818b..0000000000 --- a/examples/mp-rest-jwt/README.adoc +++ /dev/null @@ -1,329 +0,0 @@ -= MicroProfile JWT -:index-group: MicroProfile -:jbake-type: page -:jbake-status: published - -This is a basic example on how to configure and use MicroProfile JWT in -TomEE. - -== Run the tests for different scenarios related with JWT validation - -[source,java] ----- -mvn clean test ----- - -== Configuration in TomEE - -The class `MoviesMPJWTConfigurationProvider.java` provides to TomEE the -figuration need it for JWT validation. - -[source,java] ----- -package org.superbiz.moviefun.rest; - -import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo; - -import jakarta.enterprise.context.Dependent; -import jakarta.enterprise.inject.Produces; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Optional; - -@Dependent -public class MoviesMPJWTConfigurationProvider { - - @Produces - Optional<JWTAuthContextInfo> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException { - JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(); - - // todo use MP Config to load the configuration - contextInfo.setIssuedBy("https://server.example.com"); - - final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + - "nQIDAQAB"; - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - final KeyFactory kf = KeyFactory.getInstance("RSA"); - final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec); - - contextInfo.setSignerKey(pk); - - return Optional.of(contextInfo); - } - - @Produces - JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { - return getOptionalContextInfo().get(); - } -} ----- - -== Use MicroProfile JWT in TomEE - -The JAX-RS resource `MoviesRest.java` contains several endpoint that are -secured using the standard annotation `@RolesAllowed`. MicroProfile JWT -takes care of performing the validation for incoming requests with -`Authorization` header providing a signed `Access Token` - -[source,java] ----- - package org.superbiz.moviefun.rest; - - import org.superbiz.moviefun.Movie; - import org.superbiz.moviefun.MoviesBean; - - import jakarta.annotation.security.RolesAllowed; - import jakarta.inject.Inject; - import jakarta.ws.rs.*; - import jakarta.ws.rs.core.MediaType; - import java.util.List; - - @Path("cinema") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public class MoviesRest { - - @Inject - private MoviesBean moviesBean; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String status() { - return "ok"; - } - - @GET - @Path("/movies") - @RolesAllowed({"crud", "read-only"}) - public List<Movie> getListOfMovies() { - return moviesBean.getMovies(); - } - - @GET - @Path("/movies/{id}") - @RolesAllowed({"crud", "read-only"}) - public Movie getMovie(@PathParam("id") int id) { - return moviesBean.getMovie(id); - } - - @POST - @Path("/movies") - @RolesAllowed("crud") - public void addMovie(Movie newMovie) { - moviesBean.addMovie(newMovie); - } - - @DELETE - @Path("/movies/{id}") - @RolesAllowed("crud") - public void deleteMovie(@PathParam("id") int id) { - moviesBean.deleteMovie(id); - } - - @PUT - @Path("/movies") - @RolesAllowed("crud") - public void updateMovie(Movie updatedMovie) { - moviesBean.updateMovie(updatedMovie); - } - - } - - @Inject - @ConfigProperty(name = "java.runtime.version") - private String javaVersion; - ----- - -== About the Test architecture - -The test cases from this project are builded using Arquillian. The -arquillian configuration can be found in -`src/test/resources/arquillian.xml` - -The class `TokenUtils.java` is used during the test to act as an -Authorization server who generates `Access Tokens` based on the -configuration files `privateKey.pem`,`publicKey.pem`,`Token1.json`, and -`Token2.json`. + -`nimbus-jose-jwt` is the library used for JWT generation during the -tests. - -`Token1.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "j...@example.com", - "preferred_username": "jdoe", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "group1", - "group2", - "crud", - "read-only" - ] -} ----- - -`Token2.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "al...@example.com", - "preferred_username": "alice", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "read-only" - ] -} ----- - -== Test Scenarios - -`MovieTest.java` contains 4 OAuth2 scenarios for different JWT -combinations. - -[source,java] ----- -package org.superbiz.moviefun; - -import org.apache.cxf.feature.LoggingFeature; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.johnzon.jaxrs.JohnzonProvider; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.Arquillian; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.StringAsset; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.superbiz.moviefun.rest.ApplicationConfig; -import org.superbiz.moviefun.rest.MoviesMPJWTConfigurationProvider; -import org.superbiz.moviefun.rest.MoviesRest; - -import jakarta.ws.rs.core.Response; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; -import java.util.logging.Logger; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertTrue; - -@RunWith(Arquillian.class) -public class MoviesTest { - - @Deployment(testable = false) - public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") - .addClasses(Movie.class, MoviesBean.class, MoviesTest.class) - .addClasses(MoviesRest.class, ApplicationConfig.class) - .addClass(MoviesMPJWTConfigurationProvider.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); - - System.out.println(webArchive.toString(true)); - - return webArchive; - } - - @ArquillianResource - private URL base; - - - private final static Logger LOGGER = Logger.getLogger(MoviesTest.class.getName()); - - @Test - public void movieRestTest() throws Exception { - - final WebClient webClient = WebClient - .create(base.toExternalForm(), singletonList(new JohnzonProvider<>()), - singletonList(new LoggingFeature()), null); - - - //Testing rest endpoint deployment (GET without security header) - String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); - LOGGER.info("responsePayload = " + responsePayload); - assertTrue(responsePayload.equalsIgnoreCase("ok")); - - - //POST (Using token1.json with group of claims: [CRUD]) - Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); - Response response = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .post(newMovie); - LOGGER.info("responseCode = " + response.getStatus()); - assertTrue(response.getStatus() == 204); - - - //GET movies (Using token1.json with group of claims: [read-only]) - //This test should be updated to use token2.json once TOMEE- gets resolved. - Collection<? extends Movie> movies = webClient - .reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .getCollection(Movie.class); - LOGGER.info(movies.toString()); - assertTrue(movies.size() == 1); - - - //Should return a 403 since POST require group of claims: [crud] but Token 2 has only [read-only]. - Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); - Response responseWithError = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) - .post(secondNewMovie); - LOGGER.info("responseCode = " + responseWithError.getStatus()); - assertTrue(responseWithError.getStatus() == 403); - - - //Should return a 401 since the header Authorization is not part of the POST request. - Response responseWith401Error = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .post(new Movie()); - LOGGER.info("responseCode = " + responseWith401Error.getStatus()); - assertTrue(responseWith401Error.getStatus() == 401); - - } - - - private String token(int token_type) throws Exception { - HashMap<String, Long> timeClaims = new HashMap<>(); - if (token_type == 1) { - return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); - } else { - return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); - } - } - -} ----- diff --git a/examples/mp-rest-jwt/README_es.adoc b/examples/mp-rest-jwt/README_es.adoc deleted file mode 100644 index 75a0087429..0000000000 --- a/examples/mp-rest-jwt/README_es.adoc +++ /dev/null @@ -1,328 +0,0 @@ -= MicroProfile JWT -:index-group: MicroProfile -:jbake-type: page -:jbake-status: published - -Este es un ejemplo básico sobre cómo configurar y usar MicroProfile JWT en TomEE. - -== Ejecute las pruebas para diferentes escenarios relacionados con la validación JWT - -[source,java] ----- -mvn clean test ----- - -== Configuración en TomEE - -La clase `MoviesMPJWTConfigurationProvider.java` proporciona a TomEE la configuración -necesaria para la validación JWT. - -[source,java] ----- -package org.superbiz.moviefun.rest; - -import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo; - -import jakarta.enterprise.context.Dependent; -import jakarta.enterprise.inject.Produces; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Optional; - -@Dependent -public class MoviesMPJWTConfigurationProvider { - - @Produces - Optional<JWTAuthContextInfo> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException { - JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(); - - // todo use MP Config to load the configuration - contextInfo.setIssuedBy("https://server.example.com"); - - final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + - "nQIDAQAB"; - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - final KeyFactory kf = KeyFactory.getInstance("RSA"); - final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec); - - contextInfo.setSignerKey(pk); - - return Optional.of(contextInfo); - } - - @Produces - JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { - return getOptionalContextInfo().get(); - } -} ----- - -== Utilizando MicroProfile JWT en TomEE - -El recurso JAX-RS `MoviesRest.java` contiene varios puntos finales seguros, que se consiguen -mediante el uso de anotación estándar `@RolesAllowed`. MicroProfile JWT se encarga de realizar -la validación de las solicitudes entrantes con el encabezado `Authorization` -que proveen un `Access Token` firmado - -[source,java] ----- - package org.superbiz.moviefun.rest; - - import org.superbiz.moviefun.Movie; - import org.superbiz.moviefun.MoviesBean; - - import jakarta.annotation.security.RolesAllowed; - import jakarta.inject.Inject; - import jakarta.ws.rs.*; - import jakarta.ws.rs.core.MediaType; - import java.util.List; - - @Path("cinema") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public class MoviesRest { - - @Inject - private MoviesBean moviesBean; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String status() { - return "ok"; - } - - @GET - @Path("/movies") - @RolesAllowed({"crud", "read-only"}) - public List<Movie> getListOfMovies() { - return moviesBean.getMovies(); - } - - @GET - @Path("/movies/{id}") - @RolesAllowed({"crud", "read-only"}) - public Movie getMovie(@PathParam("id") int id) { - return moviesBean.getMovie(id); - } - - @POST - @Path("/movies") - @RolesAllowed("crud") - public void addMovie(Movie newMovie) { - moviesBean.addMovie(newMovie); - } - - @DELETE - @Path("/movies/{id}") - @RolesAllowed("crud") - public void deleteMovie(@PathParam("id") int id) { - moviesBean.deleteMovie(id); - } - - @PUT - @Path("/movies") - @RolesAllowed("crud") - public void updateMovie(Movie updatedMovie) { - moviesBean.updateMovie(updatedMovie); - } - - } - - @Inject - @ConfigProperty(name = "java.runtime.version") - private String javaVersion; - ----- - -== Sobre la arquitectura de prueba - -Los casos de prueba de este proyecto se construyen con Arquillian. -La configuración arquillian se puede encontrar en -`src/test/resources/arquillian.xml` - -La clase `TokenUtils.java` se utiliza durante la prueba para actuar como -un servidor de Autorización que genera `Access Tokens` basados en los archivos -de configuración `privateKey.pem`, ` publicKey.pem`, `Token1.json` y -` Token2 .json`. - -`nimbus-jose-jwt` es la libreria utilizada para la generación de JWT durante - las pruebas. - -`Token1.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "j...@example.com", - "preferred_username": "jdoe", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "group1", - "group2", - "crud", - "read-only" - ] -} ----- - -`Token2.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "al...@example.com", - "preferred_username": "alice", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "read-only" - ] -} ----- - -== Escenarios de prueba - -`MovieTest.java` contiene 4 escenarios OAuth2 para diferentes combinaciones de JWT. - -[source,java] ----- -package org.superbiz.moviefun; - -import org.apache.cxf.feature.LoggingFeature; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.johnzon.jaxrs.JohnzonProvider; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.Arquillian; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.StringAsset; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.superbiz.moviefun.rest.ApplicationConfig; -import org.superbiz.moviefun.rest.MoviesMPJWTConfigurationProvider; -import org.superbiz.moviefun.rest.MoviesRest; - -import jakarta.ws.rs.core.Response; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; -import java.util.logging.Logger; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertTrue; - -@RunWith(Arquillian.class) -public class MoviesTest { - - @Deployment(testable = false) - public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") - .addClasses(Movie.class, MoviesBean.class, MoviesTest.class) - .addClasses(MoviesRest.class, ApplicationConfig.class) - .addClass(MoviesMPJWTConfigurationProvider.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); - - System.out.println(webArchive.toString(true)); - - return webArchive; - } - - @ArquillianResource - private URL base; - - - private final static Logger LOGGER = Logger.getLogger(MoviesTest.class.getName()); - - @Test - public void movieRestTest() throws Exception { - - final WebClient webClient = WebClient - .create(base.toExternalForm(), singletonList(new JohnzonProvider<>()), - singletonList(new LoggingFeature()), null); - - - //Testing rest endpoint deployment (GET without security header) - String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); - LOGGER.info("responsePayload = " + responsePayload); - assertTrue(responsePayload.equalsIgnoreCase("ok")); - - - //POST (Using token1.json with group of claims: [CRUD]) - Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); - Response response = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .post(newMovie); - LOGGER.info("responseCode = " + response.getStatus()); - assertTrue(response.getStatus() == 204); - - - //GET movies (Using token1.json with group of claims: [read-only]) - //This test should be updated to use token2.json once TOMEE- gets resolved. - Collection<? extends Movie> movies = webClient - .reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .getCollection(Movie.class); - LOGGER.info(movies.toString()); - assertTrue(movies.size() == 1); - - - //Should return a 403 since POST require group of claims: [crud] but Token 2 has only [read-only]. - Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); - Response responseWithError = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) - .post(secondNewMovie); - LOGGER.info("responseCode = " + responseWithError.getStatus()); - assertTrue(responseWithError.getStatus() == 403); - - - //Should return a 401 since the header Authorization is not part of the POST request. - Response responseWith401Error = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .post(new Movie()); - LOGGER.info("responseCode = " + responseWith401Error.getStatus()); - assertTrue(responseWith401Error.getStatus() == 401); - - } - - - private String token(int token_type) throws Exception { - HashMap<String, Long> timeClaims = new HashMap<>(); - if (token_type == 1) { - return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); - } else { - return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); - } - } - -} ----- diff --git a/examples/mp-rest-jwt/README_pt.adoc b/examples/mp-rest-jwt/README_pt.adoc deleted file mode 100644 index 22cd407e62..0000000000 --- a/examples/mp-rest-jwt/README_pt.adoc +++ /dev/null @@ -1,318 +0,0 @@ -= MicroProfile JWT -:index-group: MicroProfile -:jbake-type: page -:jbake-status: published - -Este é um exemplo básico sobre como configurar e utilizar o MicroProfile JWT no TomEE. - -== Execute testes para diferentes cenários relacionados à validação JWT - -[source,java] ----- -mvn clean test ----- - -== Configuração no TomEE - -A classe `MoviesMPJWTConfigurationProvider.java` fornece ao TomEE as configurações necessárias para a validação do JWT. - -[source,java] ----- -package org.superbiz.moviefun.rest; - -import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo; - -import jakarta.enterprise.context.Dependent; -import jakarta.enterprise.inject.Produces; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Optional; - -@Dependent -public class MoviesMPJWTConfigurationProvider { - - @Produces - Optional<JWTAuthContextInfo> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException { - JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(); - - // todo use MP Config to load the configuration - contextInfo.setIssuedBy("https://server.example.com"); - - final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + - "nQIDAQAB"; - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - final KeyFactory kf = KeyFactory.getInstance("RSA"); - final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec); - - contextInfo.setSignerKey(pk); - - return Optional.of(contextInfo); - } - - @Produces - JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { - return getOptionalContextInfo().get(); - } -} ----- - -== Usando o MicroProfile JWT no TomEE - -O recurso JAX-RS `MoviesRest.java` contém vários endpoints que estão protegidos usando a anotação padrão `@RolesAllowed`. O MicroProfile JWT é responsável por validar solicitações recebidas com o cabeçalho `Authorization' que fornece um token de acesso assinado. - -[source,java] ----- - package org.superbiz.moviefun.rest; - - import org.superbiz.moviefun.Movie; - import org.superbiz.moviefun.MoviesBean; - - import jakarta.annotation.security.RolesAllowed; - import jakarta.inject.Inject; - import jakarta.ws.rs.*; - import jakarta.ws.rs.core.MediaType; - import java.util.List; - - @Path("cinema") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public class MoviesRest { - - @Inject - private MoviesBean moviesBean; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String status() { - return "ok"; - } - - @GET - @Path("/movies") - @RolesAllowed({"crud", "read-only"}) - public List<Movie> getListOfMovies() { - return moviesBean.getMovies(); - } - - @GET - @Path("/movies/{id}") - @RolesAllowed({"crud", "read-only"}) - public Movie getMovie(@PathParam("id") int id) { - return moviesBean.getMovie(id); - } - - @POST - @Path("/movies") - @RolesAllowed("crud") - public void addMovie(Movie newMovie) { - moviesBean.addMovie(newMovie); - } - - @DELETE - @Path("/movies/{id}") - @RolesAllowed("crud") - public void deleteMovie(@PathParam("id") int id) { - moviesBean.deleteMovie(id); - } - - @PUT - @Path("/movies") - @RolesAllowed("crud") - public void updateMovie(Movie updatedMovie) { - moviesBean.updateMovie(updatedMovie); - } - - } - - @Inject - @ConfigProperty(name = "java.runtime.version") - private String javaVersion; - ----- - -== Sobre a arquitetura de teste - -Os casos de teste para este projeto são construídos com o Arquillian. A configuração do Arquillian pode ser encontrada em `src/test/resources/arquillian.xml` - -A classe `TokenUtils.java` é usada durante o teste para atuar como um servidor de Autorização que gera `Access Tokens` com base nos arquivos de configuração `privateKey.pem`,`publicKey.pem`, `Token1.json` e `Token2.json`. - -`nimbus-jose-jwt` é a biblioteca usada para a geração do JWT durante os testes. - -`Token1.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "j...@example.com", - "preferred_username": "jdoe", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "group1", - "group2", - "crud", - "read-only" - ] -} ----- - -`Token2.json` - -[source,java] ----- -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "al...@example.com", - "preferred_username": "alice", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "read-only" - ] -} ----- - -== Cenários de teste - -`MovieTest.java` contém 4 cenários OAuth2 para diferentes combinações de JWT. - -[source,java] ----- -package org.superbiz.moviefun; - -import org.apache.cxf.feature.LoggingFeature; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.johnzon.jaxrs.JohnzonProvider; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.Arquillian; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.StringAsset; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.superbiz.moviefun.rest.ApplicationConfig; -import org.superbiz.moviefun.rest.MoviesMPJWTConfigurationProvider; -import org.superbiz.moviefun.rest.MoviesRest; - -import jakarta.ws.rs.core.Response; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; -import java.util.logging.Logger; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertTrue; - -@RunWith(Arquillian.class) -public class MoviesTest { - - @Deployment(testable = false) - public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") - .addClasses(Movie.class, MoviesBean.class, MoviesTest.class) - .addClasses(MoviesRest.class, ApplicationConfig.class) - .addClass(MoviesMPJWTConfigurationProvider.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); - - System.out.println(webArchive.toString(true)); - - return webArchive; - } - - @ArquillianResource - private URL base; - - - private final static Logger LOGGER = Logger.getLogger(MoviesTest.class.getName()); - - @Test - public void movieRestTest() throws Exception { - - final WebClient webClient = WebClient - .create(base.toExternalForm(), singletonList(new JohnzonProvider<>()), - singletonList(new LoggingFeature()), null); - - - //Testing rest endpoint deployment (GET without security header) - String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); - LOGGER.info("responsePayload = " + responsePayload); - assertTrue(responsePayload.equalsIgnoreCase("ok")); - - - //POST (Using token1.json with group of claims: [CRUD]) - Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); - Response response = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .post(newMovie); - LOGGER.info("responseCode = " + response.getStatus()); - assertTrue(response.getStatus() == 204); - - - //GET movies (Using token1.json with group of claims: [read-only]) - //This test should be updated to use token2.json once TOMEE- gets resolved. - Collection<? extends Movie> movies = webClient - .reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .getCollection(Movie.class); - LOGGER.info(movies.toString()); - assertTrue(movies.size() == 1); - - - //Should return a 403 since POST require group of claims: [crud] but Token 2 has only [read-only]. - Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); - Response responseWithError = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) - .post(secondNewMovie); - LOGGER.info("responseCode = " + responseWithError.getStatus()); - assertTrue(responseWithError.getStatus() == 403); - - - //Should return a 401 since the header Authorization is not part of the POST request. - Response responseWith401Error = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .post(new Movie()); - LOGGER.info("responseCode = " + responseWith401Error.getStatus()); - assertTrue(responseWith401Error.getStatus() == 401); - - } - - - private String token(int token_type) throws Exception { - HashMap<String, Long> timeClaims = new HashMap<>(); - if (token_type == 1) { - return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); - } else { - return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); - } - } - -} ----- diff --git a/examples/mp-rest-jwt/pom.xml b/examples/mp-rest-jwt/pom.xml deleted file mode 100644 index bc18a9abeb..0000000000 --- a/examples/mp-rest-jwt/pom.xml +++ /dev/null @@ -1,199 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - - 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>org.superbiz</groupId> - <artifactId>mp-rest-jwt</artifactId> - <version>9.0.0-M9-SNAPSHOT</version> - <packaging>war</packaging> - <name>TomEE :: Examples :: MP REST JWT</name> - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <version.jakartaee-api>9.1-M2</version.jakartaee-api> - <tomee.version>9.0.0-M9-SNAPSHOT</tomee.version> - <version.shrinkwrap.resolver>2.0.0</version.shrinkwrap.resolver> - <mp-jwt.version>1.0</mp-jwt.version> - </properties> - <build> - <defaultGoal>install</defaultGoal> - <finalName>moviefun</finalName> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>2.18.1</version> - <configuration> - <reuseForks>false</reuseForks> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-war-plugin</artifactId> - <version>3.1.0</version> - <configuration> - <failOnMissingWebXml>false</failOnMissingWebXml> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.5.1</version> - <configuration> - <source>1.8</source> - <target>1.8</target> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.tomee.maven</groupId> - <artifactId>tomee-maven-plugin</artifactId> - <version>${tomee.version}</version> - <configuration> - <tomeeClassifier>microprofile</tomeeClassifier> - <args>-Xmx512m -XX:PermSize=256m</args> - <config>${project.basedir}/src/main/tomee/</config> - </configuration> - </plugin> - - </plugins> - </build> - <dependencyManagement> - <dependencies> - <!-- Override dependency resolver with test version. This must go *BEFORE* - the Arquillian BOM. --> - <dependency> - <groupId>org.jboss.shrinkwrap.resolver</groupId> - <artifactId>shrinkwrap-resolver-bom</artifactId> - <version>${version.shrinkwrap.resolver}</version> - <scope>import</scope> - <type>pom</type> - </dependency> - <!-- Now pull in our server-based unit testing framework --> - <dependency> - <groupId>org.jboss.arquillian</groupId> - <artifactId>arquillian-bom</artifactId> - <version>1.7.0.Alpha10</version> - <scope>import</scope> - <type>pom</type> - </dependency> - </dependencies> - </dependencyManagement> - <dependencies> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>jakartaee-api</artifactId> - <version>${version.jakartaee-api}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.eclipse.microprofile.jwt</groupId> - <artifactId>microprofile-jwt-auth-api</artifactId> - <version>${mp-jwt.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.nimbusds</groupId> - <artifactId>nimbus-jose-jwt</artifactId> - <version>4.23</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.13.2</version> - <scope>test</scope> - </dependency> - <!-- - The <scope>test</scope> guarantees that non of your runtime - code is dependent on any OpenEJB classes. - --> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>openejb-cxf-rs</artifactId> - <version>${tomee.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>openejb-core</artifactId> - <version>${tomee.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>commons-lang</groupId> - <artifactId>commons-lang</artifactId> - <version>2.4</version> - </dependency> - <dependency> - <groupId>org.jboss.arquillian.junit</groupId> - <artifactId>arquillian-junit-container</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.jboss.shrinkwrap.resolver</groupId> - <artifactId>shrinkwrap-resolver-depchain</artifactId> - <type>pom</type> - <scope>test</scope> - </dependency> - </dependencies> - <profiles> - <profile> - <id>arquillian-tomee-remote</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - <dependencies> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>arquillian-tomee-remote</artifactId> - <version>${tomee.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>apache-tomee</artifactId> - <version>${tomee.version}</version> - <type>zip</type> - <classifier>microprofile</classifier> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.tomee</groupId> - <artifactId>mp-jwt</artifactId> - <version>${tomee.version}</version> - <scope>provided</scope> - </dependency> - </dependencies> - </profile> - </profiles> - <!-- - This section allows you to configure where to publish libraries for sharing. - It is not required and may be deleted. For more information see: - http://maven.apache.org/plugins/maven-deploy-plugin/ - --> - <distributionManagement> - <repository> - <id>localhost</id> - <url>file://${basedir}/target/repo/</url> - </repository> - <snapshotRepository> - <id>localhost</id> - <url>file://${basedir}/target/snapshot-repo/</url> - </snapshotRepository> - </distributionManagement> -</project> diff --git a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/Movie.java b/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/Movie.java deleted file mode 100644 index 5ec1b10e63..0000000000 --- a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/Movie.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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.superbiz.moviefun; - -import jakarta.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "movie") -public class Movie { - - private int id; - private String director; - private String title; - public Movie() { - } - - public Movie(int id, String director, String title) { - this.id = id; - this.director = director; - this.title = title; - - } - - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getDirector() { - return director; - } - - public void setDirector(String director) { - this.director = director; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @Override - public String toString() { - return "Movie{" + - "id=" + id + - ", director='" + director + '\'' + - ", title='" + title + '\'' + - '}'; - } -} \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java b/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java deleted file mode 100644 index 2230c6d6e9..0000000000 --- a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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.superbiz.moviefun; - -import jakarta.annotation.PostConstruct; -import jakarta.ejb.Stateless; -import jakarta.enterprise.context.ApplicationScoped; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -@ApplicationScoped -public class MoviesBean { - - private HashMap<Integer,Movie> MovieStore; - - - @PostConstruct - public void MovieBean() { - MovieStore = new HashMap(); - } - - public void addMovie(Movie newMovie) { - MovieStore.put(newMovie.getId(), newMovie); - } - - public void deleteMovie(int id) { - MovieStore.remove(id); - } - - public void updateMovie(Movie updatedMovie) { - MovieStore.put(updatedMovie.getId(),updatedMovie); - } - - public Movie getMovie(int id) { - return MovieStore.get(id); - } - - public List getMovies() { - Collection<Movie> Movies = MovieStore.values(); - return new ArrayList<Movie>(Movies); - - } - - -} \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java b/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java deleted file mode 100644 index e3ccc033fe..0000000000 --- a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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 - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * 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.superbiz.moviefun.rest; - -import org.eclipse.microprofile.auth.LoginConfig; - -import jakarta.ws.rs.ApplicationPath; -import jakarta.ws.rs.core.Application; - -@ApplicationPath("/rest") -@LoginConfig(authMethod = "MP-JWT") -public class ApplicationConfig extends Application { - // let the server discover the endpoints -} \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java b/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java deleted file mode 100644 index b72da48116..0000000000 --- a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.superbiz.moviefun.rest; - -import org.apache.tomee.microprofile.jwt.config.JWTAuthConfiguration; - -import jakarta.enterprise.context.Dependent; -import jakarta.enterprise.inject.Produces; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Optional; - -@Dependent -public class MoviesMPJWTConfigurationProvider { - - @Produces - Optional<JWTAuthConfiguration> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException { - final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" + - "nQIDAQAB"; - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - final KeyFactory kf = KeyFactory.getInstance("RSA"); - final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec); - - return Optional.of(JWTAuthConfiguration.authConfiguration(pk, "https://server.example.com", false)); - } - - @Produces - JWTAuthConfiguration getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { - return getOptionalContextInfo().get(); - } -} \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java b/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java deleted file mode 100644 index 4e087ff860..0000000000 --- a/examples/mp-rest-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * 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.superbiz.moviefun.rest; - -import org.superbiz.moviefun.Movie; -import org.superbiz.moviefun.MoviesBean; - -import jakarta.annotation.security.RolesAllowed; -import jakarta.inject.Inject; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import java.util.List; - -@Path("cinema") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class MoviesRest { - - @Inject - private MoviesBean moviesBean; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String status() { - return "ok"; - } - - @GET - @Path("/movies") - @RolesAllowed({"crud", "read-only"}) - public List<Movie> getListOfMovies() { - return moviesBean.getMovies(); - } - - @GET - @Path("/movies/{id}") - @RolesAllowed({"crud", "read-only"}) - public Movie getMovie(@PathParam("id") int id) { - return moviesBean.getMovie(id); - } - - @POST - @Path("/movies") - @RolesAllowed("crud") - public void addMovie(Movie newMovie) { - moviesBean.addMovie(newMovie); - } - - @DELETE - @Path("/movies/{id}") - @RolesAllowed("crud") - public void deleteMovie(@PathParam("id") int id) { - moviesBean.deleteMovie(id); - } - - @PUT - @Path("/movies") - @RolesAllowed("crud") - public void updateMovie(Movie updatedMovie) { - moviesBean.updateMovie(updatedMovie); - } - -} \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java b/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java deleted file mode 100644 index ea566dfb96..0000000000 --- a/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * 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.superbiz.moviefun; - -import org.apache.cxf.feature.LoggingFeature; -import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.johnzon.jaxrs.JohnzonProvider; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.Arquillian; -import org.jboss.arquillian.test.api.ArquillianResource; -import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.StringAsset; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.superbiz.moviefun.rest.ApplicationConfig; -import org.superbiz.moviefun.rest.MoviesMPJWTConfigurationProvider; -import org.superbiz.moviefun.rest.MoviesRest; - -import jakarta.ws.rs.core.Response; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; -import java.util.logging.Logger; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertTrue; - -@RunWith(Arquillian.class) -public class MoviesTest { - - @Deployment(testable = false) - public static WebArchive createDeployment() { - final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war") - .addClasses(Movie.class, MoviesBean.class, MoviesTest.class) - .addClasses(MoviesRest.class, ApplicationConfig.class) - .addClass(MoviesMPJWTConfigurationProvider.class) - .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml"); - - System.out.println(webArchive.toString(true)); - - return webArchive; - } - - @ArquillianResource - private URL base; - - - private final static Logger LOGGER = Logger.getLogger(MoviesTest.class.getName()); - - @Test - public void movieRestTest() throws Exception { - - final WebClient webClient = WebClient - .create(base.toExternalForm(), singletonList(new JohnzonProvider<>()), - singletonList(new LoggingFeature()), null); - - - //Testing rest endpoint deployment (GET without security header) - String responsePayload = webClient.reset().path("/rest/cinema/").get(String.class); - LOGGER.info("responsePayload = " + responsePayload); - assertTrue(responsePayload.equalsIgnoreCase("ok")); - - - //POST (Using token1.json with group of claims: [CRUD]) - Movie newMovie = new Movie(1, "David Dobkin", "Wedding Crashers"); - Response response = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(1)) - .post(newMovie); - LOGGER.info("responseCode = " + response.getStatus()); - assertTrue(response.getStatus() == 204); - - - //GET movies (Using token2.json with group of claims: [read-only]) - Collection<? extends Movie> movies = webClient - .reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) - .getCollection(Movie.class); - LOGGER.info(movies.toString()); - assertTrue(movies.size() == 1); - - - //Should return a 403 since POST require group of claims: [crud] but Token 2 has only [read-only]. - Movie secondNewMovie = new Movie(2, "Todd Phillips", "Starsky & Hutch"); - Response responseWithError = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .header("Authorization", "Bearer " + token(2)) - .post(secondNewMovie); - LOGGER.info("responseCode = " + responseWithError.getStatus()); - assertTrue(responseWithError.getStatus() == 403); - - - //Should return a 401 since the header Authorization is not part of the POST request. - Response responseWith401Error = webClient.reset() - .path("/rest/cinema/movies") - .header("Content-Type", "application/json") - .post(new Movie()); - LOGGER.info("responseCode = " + responseWith401Error.getStatus()); - assertTrue(responseWith401Error.getStatus() == 401); - - } - - - private String token(int token_type) throws Exception { - HashMap<String, Long> timeClaims = new HashMap<>(); - if (token_type == 1) { - return TokenUtils.generateTokenString("/Token1.json", null, timeClaims); - } else { - return TokenUtils.generateTokenString("/Token2.json", null, timeClaims); - } - } - -} diff --git a/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java b/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java deleted file mode 100644 index 5aa34b4905..0000000000 --- a/examples/mp-rest-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2016-2017 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed 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.superbiz.moviefun; - -import com.nimbusds.jose.JOSEObjectType; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.crypto.MACSigner; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import net.minidev.json.JSONObject; -import net.minidev.json.parser.JSONParser; -import org.eclipse.microprofile.jwt.Claims; - -import java.io.InputStream; -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE; - -/** - * Utilities for generating a JWT for testing - */ -public class TokenUtils { - private TokenUtils() { - } - - /** - * Utility method to generate a JWT string from a JSON resource file that is signed by the privateKey.pem - * test resource key. - * - * @param jsonResName - name of test resources file - * @return the JWT string - * @throws Exception on parse failure - */ - public static String generateTokenString(String jsonResName) throws Exception { - return generateTokenString(jsonResName, Collections.emptySet()); - } - - /** - * Utility method to generate a JWT string from a JSON resource file that is signed by the privateKey.pem - * test resource key, possibly with invalid fields. - * - * @param jsonResName - name of test resources file - * @param invalidClaims - the set of claims that should be added with invalid values to test failure modes - * @return the JWT string - * @throws Exception on parse failure - */ - public static String generateTokenString(String jsonResName, Set<InvalidClaims> invalidClaims) throws Exception { - return generateTokenString(jsonResName, invalidClaims, null); - } - - /** - * Utility method to generate a JWT string from a JSON resource file that is signed by the privateKey.pem - * test resource key, possibly with invalid fields. - * - * @param jsonResName - name of test resources file - * @param invalidClaims - the set of claims that should be added with invalid values to test failure modes - * @param timeClaims - used to return the exp, iat, auth_time claims - * @return the JWT string - * @throws Exception on parse failure - */ - public static String generateTokenString(String jsonResName, Set<InvalidClaims> invalidClaims, Map<String, Long> timeClaims) throws Exception { - if (invalidClaims == null) { - invalidClaims = Collections.emptySet(); - } - InputStream contentIS = TokenUtils.class.getResourceAsStream(jsonResName); - byte[] tmp = new byte[4096]; - int length = contentIS.read(tmp); - byte[] content = new byte[length]; - System.arraycopy(tmp, 0, content, 0, length); - - JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE); - JSONObject jwtContent = (JSONObject) parser.parse(content); - // Change the issuer to INVALID_ISSUER for failure testing if requested - if (invalidClaims.contains(InvalidClaims.ISSUER)) { - jwtContent.put(Claims.iss.name(), "INVALID_ISSUER"); - } - long currentTimeInSecs = currentTimeInSecs(); - long exp = currentTimeInSecs + 300; - // Check for an input exp to override the default of now + 300 seconds - if (timeClaims != null && timeClaims.containsKey(Claims.exp.name())) { - exp = timeClaims.get(Claims.exp.name()); - } - jwtContent.put(Claims.iat.name(), currentTimeInSecs); - jwtContent.put(Claims.auth_time.name(), currentTimeInSecs); - // If the exp claim is not updated, it will be an old value that should be seen as expired - if (!invalidClaims.contains(InvalidClaims.EXP)) { - jwtContent.put(Claims.exp.name(), exp); - } - if (timeClaims != null) { - timeClaims.put(Claims.iat.name(), currentTimeInSecs); - timeClaims.put(Claims.auth_time.name(), currentTimeInSecs); - timeClaims.put(Claims.exp.name(), exp); - } - - PrivateKey pk; - if (invalidClaims.contains(InvalidClaims.SIGNER)) { - // Generate a new random private key to sign with to test invalid signatures - KeyPair keyPair = generateKeyPair(2048); - pk = keyPair.getPrivate(); - } else { - // Use the test private key associated with the test public key for a valid signature - pk = readPrivateKey("/privateKey.pem"); - } - - // Create RSA-signer with the private key - JWSSigner signer = new RSASSASigner(pk); - JWTClaimsSet claimsSet = JWTClaimsSet.parse(jwtContent); - JWSAlgorithm alg = JWSAlgorithm.RS256; - if (invalidClaims.contains(InvalidClaims.ALG)) { - alg = JWSAlgorithm.HS256; - SecureRandom random = new SecureRandom(); - BigInteger secret = BigInteger.probablePrime(256, random); - signer = new MACSigner(secret.toByteArray()); - } - JWSHeader jwtHeader = new JWSHeader.Builder(alg) - .keyID("/privateKey.pem") - .type(JOSEObjectType.JWT) - .build(); - SignedJWT signedJWT = new SignedJWT(jwtHeader, claimsSet); - signedJWT.sign(signer); - return signedJWT.serialize(); - } - - /** - * Read a PEM encoded private key from the classpath - * - * @param pemResName - key file resource name - * @return PrivateKey - * @throws Exception on decode failure - */ - public static PrivateKey readPrivateKey(String pemResName) throws Exception { - InputStream contentIS = TokenUtils.class.getResourceAsStream(pemResName); - byte[] tmp = new byte[4096]; - int length = contentIS.read(tmp); - return decodePrivateKey(new String(tmp, 0, length)); - } - - /** - * Read a PEM encoded public key from the classpath - * - * @param pemResName - key file resource name - * @return PublicKey - * @throws Exception on decode failure - */ - public static PublicKey readPublicKey(String pemResName) throws Exception { - InputStream contentIS = TokenUtils.class.getResourceAsStream(pemResName); - byte[] tmp = new byte[4096]; - int length = contentIS.read(tmp); - return decodePublicKey(new String(tmp, 0, length)); - } - - /** - * Generate a new RSA keypair. - * - * @param keySize - the size of the key - * @return KeyPair - * @throws NoSuchAlgorithmException on failure to load RSA key generator - */ - public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(keySize); - return keyPairGenerator.genKeyPair(); - } - - /** - * Decode a PEM encoded private key string to an RSA PrivateKey - * - * @param pemEncoded - PEM string for private key - * @return PrivateKey - * @throws Exception on decode failure - */ - public static PrivateKey decodePrivateKey(String pemEncoded) throws Exception { - pemEncoded = removeBeginEnd(pemEncoded); - byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(pemEncoded); - - // extract the private key - - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePrivate(keySpec); - } - - /** - * Decode a PEM encoded public key string to an RSA PublicKey - * - * @param pemEncoded - PEM string for private key - * @return PublicKey - * @throws Exception on decode failure - */ - public static PublicKey decodePublicKey(String pemEncoded) throws Exception { - pemEncoded = removeBeginEnd(pemEncoded); - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePublic(spec); - } - - private static String removeBeginEnd(String pem) { - pem = pem.replaceAll("-----BEGIN (.*)-----", ""); - pem = pem.replaceAll("-----END (.*)----", ""); - pem = pem.replaceAll("\r\n", ""); - pem = pem.replaceAll("\n", ""); - return pem.trim(); - } - - /** - * @return the current time in seconds since epoch - */ - public static int currentTimeInSecs() { - long currentTimeMS = System.currentTimeMillis(); - return (int) (currentTimeMS / 1000); - } - - /** - * Enums to indicate which claims should be set to invalid values for testing failure modes - */ - public enum InvalidClaims { - ISSUER, // Set an invalid issuer - EXP, // Set an invalid expiration - SIGNER, // Sign the token with the incorrect private key - ALG, // Sign the token with the correct private key, but HS - } -} diff --git a/examples/mp-rest-jwt/src/test/resources/META-INF/application-client.xml b/examples/mp-rest-jwt/src/test/resources/META-INF/application-client.xml deleted file mode 100644 index 2ce910f23a..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/META-INF/application-client.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<application-client/> diff --git a/examples/mp-rest-jwt/src/test/resources/Token1.json b/examples/mp-rest-jwt/src/test/resources/Token1.json deleted file mode 100644 index 2766575518..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/Token1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "j...@example.com", - "preferred_username": "jdoe", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "group1", - "group2", - "crud", - "read-only" - ] -} diff --git a/examples/mp-rest-jwt/src/test/resources/Token2.json b/examples/mp-rest-jwt/src/test/resources/Token2.json deleted file mode 100644 index f591863e98..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/Token2.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "iss": "https://server.example.com", - "jti": "a-123", - "sub": "24400320", - "upn": "al...@example.com", - "preferred_username": "alice", - "aud": "s6BhdRkqt3", - "exp": 1311281970, - "iat": 1311280970, - "auth_time": 1311280969, - "groups": [ - "read-only" - ] -} diff --git a/examples/mp-rest-jwt/src/test/resources/arquillian.xml b/examples/mp-rest-jwt/src/test/resources/arquillian.xml deleted file mode 100644 index 4744e7a89a..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/arquillian.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<!-- - - 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. ---> -<arquillian - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - > - - <container qualifier="tomee" default="true"> - <configuration> - <property name="httpPort">-1</property> - <property name="stopPort">-1</property> - <property name="classifier">microprofile</property> - <property name="dir">target/apache-tomee-remote</property> - <property name="appWorkingDir">target/arquillian-test-working-dir</property> - </configuration> - </container> -</arquillian> \ No newline at end of file diff --git a/examples/mp-rest-jwt/src/test/resources/privateKey.pem b/examples/mp-rest-jwt/src/test/resources/privateKey.pem deleted file mode 100644 index e20d80b58d..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/privateKey.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa -PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H -OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN -qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh -nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM -uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6 -oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv -6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY -URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6 -96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB -Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3 -zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF -KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP -iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B -m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS -34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG -5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2 -tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL -WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y -b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09 -nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB -MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d -Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe -Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt -FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8 -f3cg+fr8aou7pr9SHhJlZCU= ------END RSA PRIVATE KEY----- diff --git a/examples/mp-rest-jwt/src/test/resources/publicKey.pem b/examples/mp-rest-jwt/src/test/resources/publicKey.pem deleted file mode 100644 index a1dc20c8c8..0000000000 --- a/examples/mp-rest-jwt/src/test/resources/publicKey.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq -Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR -TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e -UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9 -AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn -sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x -nQIDAQAB ------END RSA PUBLIC KEY----- diff --git a/examples/pom.xml b/examples/pom.xml index 4879ca5d2c..fd39642833 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -126,7 +126,6 @@ <module>mp-metrics-gauge</module> <module>mp-metrics-metered</module> <module>mp-opentracing-traced</module> - <module>mp-rest-jwt</module> <module>mp-rest-jwt-jwk</module> <module>mp-rest-jwt-principal</module> <module>mp-rest-jwt-public-key</module>