tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlmonte...@apache.org
Subject [1/7] tomee git commit: TOMEE-2334: example for Principal usage in MicroProfile JWT with TomEE
Date Wed, 02 Jan 2019 09:59:13 GMT
Repository: tomee
Updated Branches:
  refs/heads/master 3b2d562f8 -> 5c047f803


TOMEE-2334: example for Principal usage in MicroProfile JWT with TomEE


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/83a1a56d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/83a1a56d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/83a1a56d

Branch: refs/heads/master
Commit: 83a1a56d5c44fce919edb2c8cdc236042eefa8bf
Parents: b489fca
Author: cotnic <mitja@cotnic.com>
Authored: Mon Dec 31 19:25:50 2018 +0100
Committer: cotnic <mitja@cotnic.com>
Committed: Mon Dec 31 19:25:50 2018 +0100

----------------------------------------------------------------------
 examples/mp-rest-jwt-principal/README.adoc      | 103 +++++++++++
 examples/mp-rest-jwt-principal/pom.xml          | 184 +++++++++++++++++++
 .../java/org/superbiz/store/entity/Order.java   |  69 +++++++
 .../java/org/superbiz/store/entity/Product.java |  69 +++++++
 .../java/org/superbiz/store/rest/OrderRest.java | 102 ++++++++++
 .../superbiz/store/rest/RestApplication.java    |  27 +++
 .../superbiz/store/service/OrderService.java    |  75 ++++++++
 .../META-INF/microprofile-config.properties     |   2 +
 .../src/main/resources/publicKey.pem            |   8 +
 .../org/superbiz/store/GenerateKeyUtils.java    |  37 ++++
 .../org/superbiz/store/OrderRestClient.java     |  60 ++++++
 .../java/org/superbiz/store/OrdersTest.java     | 161 ++++++++++++++++
 .../java/org/superbiz/store/TokenUtils.java     |  83 +++++++++
 .../META-INF/microprofile-config.properties     |   3 +
 .../src/test/resources/alice-wonder-jwt.json    |  10 +
 .../src/test/resources/arquillian.xml           |  38 ++++
 .../src/test/resources/john-doe-jwt.json        |  10 +
 .../src/test/resources/privateKey.pem           |  24 +++
 18 files changed, 1065 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/README.adoc
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/README.adoc b/examples/mp-rest-jwt-principal/README.adoc
new file mode 100644
index 0000000..5fc3dbd
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/README.adoc
@@ -0,0 +1,103 @@
+= MicroProfile JWT Principal
+:index-group: MicroProfile
+:jbake-type: page
+:jbake-status: published
+
+This is an example on how to use MicroProfile JWT in TomEE by accessing
+Principal from the JsonWebToken.
+
+== Run the application:
+
+[source, bash]
+----
+mvn clean install tomee:run
+----
+
+This example is a CRUD application for orders in store.
+
+== Requirments and configuration
+
+For usage of MicroProfile JWT we have to change the following to our
+project:
+
+[arabic]
+. Add the dependency to our `pom.xml` file:
++
+....
+<dependency>
+    <groupId>org.eclipse.microprofile.jwt</groupId>
+    <artifactId>microprofile-jwt-auth-api</artifactId>
+    <version>${mp-jwt.version}</version>
+    <scope>provided</scope>
+</dependency>
+....
+. Annotate our `Application.class` with `@LoginConfig(authMethod = "MP-JWT")`
+
+. Provide public and private key for authentication. And specify the location of the public key and the issuer in our
+`microprofile-config.properties` file.
++
+[source,properties]
+----
+mp.jwt.verify.publickey.location=/publicKey.pem
+mp.jwt.verify.issuer=https://example.com
+----
+
+. Define `@RolesAllowed()` on the endpoints we want to protect.
+
+== Obtaining the JWT Principal
+
+We obtain the `Principal` in the MicroProfile class `org.eclipse.microprofile.jwt.JsonWebToken`. From there
+we can acquire username and groups of the user that is accessing the endpoint.
+
+[source,java]
+----
+@Inject
+private JsonWebToken jwtPrincipal;
+----
+
+== About the application architecture
+
+The application enables us to manipulate orders with specific users. We have two users `Alice Wonder`
+and `John Doe`. They can read, create, edit and delete specific entries. And for each creation
+we save the user who created the order. In case a user edits the entry we record that by accessing
+the `Principal` who has sent the request to our backend.
+
+`alice-wonder-jwt.json`
+
+[source,json]
+----
+{
+  "iss": "https://example.com",
+  "upn": "alice",
+  "sub": "alice.wonder@example.com",
+  "name": "Alice Wonder",
+  "iat": 1516239022,
+  "groups": [
+    "buyer"
+  ]
+}
+----
+
+`john-doe-jwt.json`
+[source,json]
+----
+{
+  "iss": "https://example.com",
+  "upn": "john",
+  "sub": "john.doe@example.com",
+  "name": "John Doe",
+  "iat": 1516239022,
+  "groups": [
+    "merchant"
+  ]
+}
+----
+
+== Access the endpoints with JWT token
+
+We access endpoints from our test class by creating a `JWT` with the help of
+our `TokenUtils.generateJWTString(String jsonResource)` which signs our user
+data in json format with the help of our `src/test/resources/privateKey.pem` key.
+
+We can also generate new `privateKey.pem` and `publicKey.pem` with the
+`GenerateKeyUtils.generateKeyPair(String keyAlgorithm, int keySize)` method.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/pom.xml
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/pom.xml b/examples/mp-rest-jwt-principal/pom.xml
new file mode 100644
index 0000000..cf9bb05
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/pom.xml
@@ -0,0 +1,184 @@
+<?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-principal</artifactId>
+    <version>8.0.0-SNAPSHOT</version>
+    <packaging>war</packaging>
+    <name>OpenEJB :: Examples :: MP REST JWT PRINCIPAL</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <tomee.version>8.0.0-SNAPSHOT</tomee.version>
+        <junit.version>4.23</junit.version>
+        <arquillian-bom.version>1.4.1.Final</arquillian-bom.version>
+        <mp-jwt.version>1.1.1</mp-jwt.version>
+        <mp-config.version>1.0</mp-config.version>
+        <mp-rest-client.version>1.1</mp-rest-client.version>
+    </properties>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+        <finalName>phonestore</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>
+            </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>
+            <!-- Now pull in our server-based unit testing framework -->
+            <dependency>
+                <groupId>org.jboss.arquillian</groupId>
+                <artifactId>arquillian-bom</artifactId>
+                <version>${arquillian-bom.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tomee</groupId>
+            <artifactId>javaee-api</artifactId>
+            <version>8.0</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>org.eclipse.microprofile.rest.client</groupId>
+            <artifactId>microprofile-rest-client-api</artifactId>
+            <version>${mp-rest-client.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.microprofile.config</groupId>
+            <artifactId>microprofile-config-api</artifactId>
+            <version>${mp-config.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.arquillian.junit</groupId>
+            <artifactId>arquillian-junit-container</artifactId>
+            <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>

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Order.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Order.java b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Order.java
new file mode 100644
index 0000000..26a25bf
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Order.java
@@ -0,0 +1,69 @@
+/**
+ * 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.store.entity;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public class Order {
+
+    private Integer id;
+    private String createdUser;
+    private String updatedUser;
+    private BigDecimal orderPrice;
+    private List<Product> products;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getCreatedUser() {
+        return createdUser;
+    }
+
+    public void setCreatedUser(String createdUser) {
+        this.createdUser = createdUser;
+    }
+
+    public String getUpdatedUser() {
+        return updatedUser;
+    }
+
+    public void setUpdatedUser(String updatedUser) {
+        this.updatedUser = updatedUser;
+    }
+
+    public BigDecimal getOrderPrice() {
+        return orderPrice;
+    }
+
+    public void setOrderPrice(BigDecimal orderPrice) {
+        this.orderPrice = orderPrice;
+    }
+
+    public List<Product> getProducts() {
+        return products;
+    }
+
+    public void setProducts(List<Product> products) {
+        this.products = products;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Product.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Product.java b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Product.java
new file mode 100644
index 0000000..4940e7e
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/entity/Product.java
@@ -0,0 +1,69 @@
+/**
+ * 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.store.entity;
+
+import java.math.BigDecimal;
+
+public class Product {
+
+    private Integer id;
+    private String name;
+    private BigDecimal price;
+    private Integer stock;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public void setPrice(BigDecimal price) {
+        this.price = price;
+    }
+
+    public Integer getStock() {
+        return stock;
+    }
+
+    public void setStock(Integer stock) {
+        this.stock = stock;
+    }
+
+    @Override
+    public String toString() {
+        return "Product{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", price=" + price +
+                ", stock=" + stock +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/OrderRest.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/OrderRest.java b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/OrderRest.java
new file mode 100644
index 0000000..4ef7499
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/OrderRest.java
@@ -0,0 +1,102 @@
+/**
+ * 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.store.rest;
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+import org.superbiz.store.entity.Order;
+import org.superbiz.store.service.OrderService;
+
+import javax.annotation.security.RolesAllowed;
+import javax.inject.Inject;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+@Path("store")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class OrderRest {
+
+    @Inject
+    private OrderService orderService;
+
+    @Inject
+    private JsonWebToken jwtPrincipal;
+
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    public String status() throws Exception {
+        return "running";
+    }
+
+    @GET
+    @Path("/userinfo")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String userInfo() {
+        return "User: " + jwtPrincipal.getName() + " is in groups " + jwtPrincipal.getGroups();
+    }
+
+    @GET
+    @Path("/orders")
+    @RolesAllowed({"merchant", "buyer"})
+    public List<Order> getListOfOrders() {
+        return orderService.getOrders();
+    }
+
+    @GET
+    @Path("/orders/{id}")
+    @RolesAllowed({"merchant", "buyer"})
+    public Order getOrder(@PathParam("id") int id) {
+        return orderService.getOrder(id);
+    }
+
+    @POST
+    @Path("/orders")
+    @RolesAllowed({"merchant", "buyer"})
+    public Response addOrder(Order order) {
+        Order createdOrder = orderService.addOrder(order, jwtPrincipal.getName());
+
+        return Response
+                .status(Response.Status.CREATED)
+                .entity(createdOrder)
+                .build();
+    }
+
+    @DELETE
+    @Path("/orders/{id}")
+    @RolesAllowed({"merchant"})
+    public Response deleteOrder(@PathParam("id") int id) {
+        orderService.deleteOrder(id);
+
+        return Response
+                .status(Response.Status.NO_CONTENT)
+                .build();
+    }
+
+    @PUT
+    @Path("/orders")
+    @RolesAllowed({"merchant", "buyer"})
+    public Response updateOrder(Order order) {
+        Order updatedOrder = orderService.updateOrder(order, jwtPrincipal.getName());
+
+        return Response
+                .status(Response.Status.OK)
+                .entity(updatedOrder)
+                .build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/RestApplication.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/RestApplication.java b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/RestApplication.java
new file mode 100644
index 0000000..d9e7610
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/rest/RestApplication.java
@@ -0,0 +1,27 @@
+/**
+ * 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.store.rest;
+
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/rest")
+@LoginConfig(authMethod = "MP-JWT")
+public class RestApplication extends Application {
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/service/OrderService.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/service/OrderService.java b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/service/OrderService.java
new file mode 100644
index 0000000..dcf19bc
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/java/org/superbiz/store/service/OrderService.java
@@ -0,0 +1,75 @@
+/**
+ * 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.store.service;
+
+import org.superbiz.store.entity.Order;
+import org.superbiz.store.entity.Product;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@ApplicationScoped
+public class OrderService {
+
+    private Map<Integer, Order> ordersInStore;
+
+    @PostConstruct
+    public void ProductService() {
+        ordersInStore = new HashMap();
+    }
+
+    public List<Order> getOrders() {
+        return new ArrayList<>(ordersInStore.values());
+    }
+
+    public Order getOrder(int id) {
+        return ordersInStore.get(id);
+    }
+
+    public Order addOrder(Order order, String user) {
+        order.setOrderPrice(calculateOrderPrice(order));
+        order.setCreatedUser(user);
+
+        ordersInStore.put(order.getId(), order);
+
+        return order;
+    }
+
+    public void deleteOrder(int id) {
+        ordersInStore.remove(id);
+    }
+
+    public Order updateOrder(Order order, String user) {
+        order.setOrderPrice(calculateOrderPrice(order));
+        order.setUpdatedUser(user);
+
+        ordersInStore.put(order.getId(), order);
+
+        return order;
+    }
+
+    private BigDecimal calculateOrderPrice(Order order) {
+        return order.getProducts().stream()
+                .map(Product::getPrice)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/resources/META-INF/microprofile-config.properties
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/resources/META-INF/microprofile-config.properties b/examples/mp-rest-jwt-principal/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..c1ca2e6
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,2 @@
+mp.jwt.verify.publickey.location=/publicKey.pem
+mp.jwt.verify.issuer=https://example.com
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/main/resources/publicKey.pem
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/main/resources/publicKey.pem b/examples/mp-rest-jwt-principal/src/main/resources/publicKey.pem
new file mode 100644
index 0000000..39afa14
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/main/resources/publicKey.pem
@@ -0,0 +1,8 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApaNAV+HrffoQiXv1F7uqxup406191W0t
+CBcJYzXaSCqA9Y64sRIeMLNO6L8iz1yz8VmWIwMRGjcGRQKH4ddInrHNtKdsdRUC/tbvR4wD/04V
+gFR5Lm00jz3rHb2w1znn6GmdEzE1QoFUdRRzA+M0WJ+A0E6f9g7zXfJuHIsRkZVBfhRBxmKgvryH
+t1sdlItOoZFwwEz+3PDNcMEfFRJ8EfOixhtSIyX1VSSal4ychycBdZNQLAjqrCLf0MMXqPQfuqYy
+z4/4CE09yLoKqsoMfIwe2RgrGTYdHfa7z9sMSI9x1CHSYY7tx/h63weYBHSAhWBqaU0WyvYrUtLl
++xmorQIDAQAB
+-----END PUBLIC KEY-----

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/GenerateKeyUtils.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/GenerateKeyUtils.java b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/GenerateKeyUtils.java
new file mode 100644
index 0000000..e9d9f95
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/GenerateKeyUtils.java
@@ -0,0 +1,37 @@
+/**
+ * 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.store;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+
+public class GenerateKeyUtils {
+    public static void generateKeyPair(String keyAlgorithm, int keySize) throws NoSuchAlgorithmException {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgorithm); // RSA
+        kpg.initialize(keySize); // 2048
+        KeyPair kp = kpg.generateKeyPair();
+
+        System.out.println("-----BEGIN PRIVATE KEY-----");
+        System.out.println(Base64.getMimeEncoder().encodeToString(kp.getPrivate().getEncoded()));
+        System.out.println("-----END PRIVATE KEY-----");
+        System.out.println("-----BEGIN PUBLIC KEY-----");
+        System.out.println(Base64.getMimeEncoder().encodeToString(kp.getPublic().getEncoded()));
+        System.out.println("-----END PUBLIC KEY-----");
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrderRestClient.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrderRestClient.java b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrderRestClient.java
new file mode 100644
index 0000000..9f47955
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrderRestClient.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <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.store;
+
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+import org.superbiz.store.entity.Order;
+
+import javax.enterprise.context.Dependent;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+@Dependent
+@RegisterRestClient
+@Path("/test/rest/store/")
+@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
+@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
+public interface OrderRestClient {
+    @GET
+    String status();
+
+    @GET
+    @Path("/userinfo")
+    String getUserInfo(@HeaderParam("Authorization") String authHeaderValue);
+
+    @GET
+    @Path("/orders/{id}")
+    Response getOrder(@HeaderParam("Authorization") String authHeaderValue, @PathParam("id") int id);
+
+    @GET
+    @Path("/orders")
+    List<Order> getOrders(@HeaderParam("Authorization") String authHeaderValue);
+
+    @POST
+    @Path("/orders")
+    Response addOrder(@HeaderParam("Authorization") String authHeaderValue, Order newOrder);
+
+    @PUT
+    @Path("/orders")
+    Response updateOrder(@HeaderParam("Authorization") String authHeaderValue, Order updatedOrder);
+
+    @DELETE
+    @Path("/orders/{id}")
+    Response deleteOrder(@HeaderParam("Authorization") String authHeaderValue, @PathParam("id") int id);
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrdersTest.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrdersTest.java b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrdersTest.java
new file mode 100644
index 0000000..2768f64
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/OrdersTest.java
@@ -0,0 +1,161 @@
+/**
+ * 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.store;
+
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.superbiz.store.entity.Order;
+import org.superbiz.store.entity.Product;
+import org.superbiz.store.rest.OrderRest;
+import org.superbiz.store.rest.RestApplication;
+import org.superbiz.store.service.OrderService;
+
+import javax.inject.Inject;
+import javax.ws.rs.core.Response;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class OrdersTest {
+
+    private final static Logger LOGGER = Logger.getLogger(OrdersTest.class.getName());
+
+    @Inject
+    @RestClient
+    private OrderRestClient orderRestClient;
+
+    @Deployment()
+    public static WebArchive createDeployment() {
+        final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
+                .addClasses(OrderRest.class, RestApplication.class)
+                .addClasses(Order.class, Product.class)
+                .addClass(OrderService.class)
+                .addClasses(OrderRestClient.class, TokenUtils.class)
+                .addPackages(true, "com.nimbusds", "net.minidev.json")
+                .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml")
+                .addAsResource("META-INF/microprofile-config.properties")
+                .addAsResource("john-doe-jwt.json")
+                .addAsResource("alice-wonder-jwt.json")
+                .addAsResource("privateKey.pem")
+                .addAsResource("publicKey.pem");
+        return webArchive;
+    }
+
+    @Test
+    public void shouldBeRunning() {
+        assertEquals("running", orderRestClient.status());
+    }
+
+    @Test
+    public void shouldReturnUserInfo() throws Exception {
+        assertEquals("User: john is in groups [merchant]", orderRestClient.getUserInfo("Bearer " + createJwtToken(true)));
+    }
+
+    @Test
+    public void shouldReturnOrder() throws Exception {
+        int statusCode = orderRestClient.addOrder("Bearer " + createJwtToken(true), createTestOrder()).getStatus();
+
+        assertEquals(Response.Status.CREATED.getStatusCode(), statusCode);
+
+        Order order = orderRestClient.getOrder("Bearer " + createJwtToken(false), 1).readEntity(Order.class);
+
+        assertEquals("john", order.getCreatedUser());
+    }
+
+    @Test
+    public void shouldReturnListOfOrders() throws Exception {
+        List<Order> ordersList = orderRestClient.getOrders("Bearer " + createJwtToken(true));
+        assertEquals(0, ordersList.size());
+    }
+
+    @Test
+    public void shouldSaveOrder() throws Exception {
+        Order newOrder = orderRestClient.addOrder("Bearer " + createJwtToken(true), createTestOrder()).readEntity(Order.class);
+
+        assertEquals("john", newOrder.getCreatedUser());
+    }
+
+    @Test
+    public void shouldUpdateOrder() throws Exception {
+        Order newOrder = orderRestClient.addOrder("Bearer " + createJwtToken(true), createTestOrder()).readEntity(Order.class);
+
+        assertEquals("john", newOrder.getCreatedUser());
+        assertEquals(null, newOrder.getUpdatedUser());
+
+        newOrder.setOrderPrice(new BigDecimal(1000));
+        Order updatedOrder = orderRestClient.updateOrder("Bearer " + createJwtToken(false), newOrder).readEntity(Order.class);
+
+        assertEquals("alice", updatedOrder.getUpdatedUser());
+    }
+
+    @Test
+    public void shouldDeleteOrder() throws Exception {
+        int statusCode = orderRestClient.addOrder("Bearer " + createJwtToken(true), createTestOrder()).getStatus();
+
+        assertEquals(Response.Status.CREATED.getStatusCode(), statusCode);
+
+        statusCode = orderRestClient.deleteOrder("Bearer " + createJwtToken(true), 1).getStatus();
+
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), statusCode);
+    }
+
+    @Test
+    @Ignore
+    public void shouldNotHaveAccess() throws Exception {
+        int statusCode = orderRestClient.deleteOrder("Bearer " + createJwtToken(false), 1).getStatus();
+
+        assertEquals(Response.Status.FORBIDDEN.getStatusCode(), statusCode);
+    }
+
+    public String createJwtToken(boolean john) throws Exception {
+        return TokenUtils.generateJWTString((john ? "john-doe-jwt.json" : "alice-wonder-jwt.json"));
+    }
+
+    private Order createTestOrder() {
+        List<Product> products = new ArrayList<>();
+        Product huaweiProduct = new Product();
+        huaweiProduct.setId(1);
+        huaweiProduct.setName("Huawei P20 Lite");
+        huaweiProduct.setPrice(new BigDecimal(203.31));
+        huaweiProduct.setStock(2);
+        products.add(huaweiProduct);
+
+        Product samsungProduct = new Product();
+        samsungProduct.setId(2);
+        samsungProduct.setName("Samsung S9");
+        samsungProduct.setPrice(new BigDecimal(821.42));
+        samsungProduct.setStock(1);
+        products.add(samsungProduct);
+
+        Order order = new Order();
+        order.setId(1);
+        order.setProducts(products);
+
+        return order;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/TokenUtils.java
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/TokenUtils.java b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/TokenUtils.java
new file mode 100644
index 0000000..503d14f
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/java/org/superbiz/store/TokenUtils.java
@@ -0,0 +1,83 @@
+/**
+ * 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.store;
+
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jwt.SignedJWT;
+import net.minidev.json.JSONObject;
+import net.minidev.json.parser.JSONParser;
+import org.eclipse.microprofile.jwt.Claims;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Base64;
+
+import static com.nimbusds.jose.JOSEObjectType.JWT;
+import static com.nimbusds.jose.JWSAlgorithm.RS256;
+import static com.nimbusds.jwt.JWTClaimsSet.parse;
+import static java.lang.Thread.currentThread;
+import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE;
+
+public class TokenUtils {
+
+    public static String generateJWTString(String jsonResource) throws Exception {
+        byte[] byteBuffer = new byte[16384];
+        currentThread().getContextClassLoader()
+                .getResource(jsonResource)
+                .openStream()
+                .read(byteBuffer);
+
+        JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE);
+        JSONObject jwtJson = (JSONObject) parser.parse(byteBuffer);
+
+        long currentTimeInSecs = (System.currentTimeMillis() / 1000);
+        long expirationTime = currentTimeInSecs + 1000;
+
+        jwtJson.put(Claims.iat.name(), currentTimeInSecs);
+        jwtJson.put(Claims.auth_time.name(), currentTimeInSecs);
+        jwtJson.put(Claims.exp.name(), expirationTime);
+
+        SignedJWT signedJWT = new SignedJWT(new JWSHeader
+                .Builder(RS256)
+                .keyID("/privateKey.pem")
+                .type(JWT)
+                .build(), parse(jwtJson));
+
+        signedJWT.sign(new RSASSASigner(readPrivateKey("privateKey.pem")));
+
+        return signedJWT.serialize();
+    }
+
+    public static PrivateKey readPrivateKey(String resourceName) throws Exception {
+        byte[] byteBuffer = new byte[16384];
+        int length = currentThread().getContextClassLoader()
+                .getResource(resourceName)
+                .openStream()
+                .read(byteBuffer);
+
+        String key = new String(byteBuffer, 0, length).replaceAll("-----BEGIN (.*)-----", "")
+                .replaceAll("-----END (.*)----", "")
+                .replaceAll("\r\n", "")
+                .replaceAll("\n", "")
+                .trim();
+
+        return KeyFactory.getInstance("RSA")
+                .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(key)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/resources/META-INF/microprofile-config.properties
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/resources/META-INF/microprofile-config.properties b/examples/mp-rest-jwt-principal/src/test/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..7cf428f
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,3 @@
+org.superbiz.store.OrderRestClient/mp-rest/url=http://localhost:4444
+mp.jwt.verify.publickey.location=/publicKey.pem
+mp.jwt.verify.issuer=https://example.com
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/resources/alice-wonder-jwt.json
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/resources/alice-wonder-jwt.json b/examples/mp-rest-jwt-principal/src/test/resources/alice-wonder-jwt.json
new file mode 100644
index 0000000..e2c6d34
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/resources/alice-wonder-jwt.json
@@ -0,0 +1,10 @@
+{
+  "iss": "https://example.com",
+  "upn": "alice",
+  "sub": "alice.wonder@example.com",
+  "name": "Alice Wonder",
+  "iat": 1516239022,
+  "groups": [
+    "buyer"
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/resources/arquillian.xml b/examples/mp-rest-jwt-principal/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..534eb1c
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/resources/arquillian.xml
@@ -0,0 +1,38 @@
+<?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="http://jboss.org/schema/arquillian"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="
+              http://jboss.org/schema/arquillian
+              http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+  <container qualifier="server" default="true">
+    <configuration>
+      <property name="httpsPort">-1</property>
+      <property name="httpPort">4444</property>
+      <property name="stopPort">-1</property>
+      <property name="ajpPort">-1</property>
+      <property name="classifier">microprofile</property>
+      <property name="simpleLog">true</property>
+      <property name="cleanOnStartUp">true</property>
+      <property name="dir">target/server</property>
+      <property name="appWorkingDir">target/arquillian</property>
+    </configuration>
+  </container>
+</arquillian>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/resources/john-doe-jwt.json
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/resources/john-doe-jwt.json b/examples/mp-rest-jwt-principal/src/test/resources/john-doe-jwt.json
new file mode 100644
index 0000000..7c9155f
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/resources/john-doe-jwt.json
@@ -0,0 +1,10 @@
+{
+  "iss": "https://example.com",
+  "upn": "john",
+  "sub": "john.doe@example.com",
+  "name": "John Doe",
+  "iat": 1516239022,
+  "groups": [
+    "merchant"
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/83a1a56d/examples/mp-rest-jwt-principal/src/test/resources/privateKey.pem
----------------------------------------------------------------------
diff --git a/examples/mp-rest-jwt-principal/src/test/resources/privateKey.pem b/examples/mp-rest-jwt-principal/src/test/resources/privateKey.pem
new file mode 100644
index 0000000..a058305
--- /dev/null
+++ b/examples/mp-rest-jwt-principal/src/test/resources/privateKey.pem
@@ -0,0 +1,24 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQClo0BX4et9+hCJe/UXu6rG6njT
+rX3VbS0IFwljNdpIKoD1jrixEh4ws07ovyLPXLPxWZYjAxEaNwZFAofh10iesc20p2x1FQL+1u9H
+jAP/ThWAVHkubTSPPesdvbDXOefoaZ0TMTVCgVR1FHMD4zRYn4DQTp/2DvNd8m4cixGRlUF+FEHG
+YqC+vIe3Wx2Ui06hkXDATP7c8M1wwR8VEnwR86LGG1IjJfVVJJqXjJyHJwF1k1AsCOqsIt/Qwxeo
+9B+6pjLPj/gITT3Iugqqygx8jB7ZGCsZNh0d9rvP2wxIj3HUIdJhju3H+HrfB5gEdICFYGppTRbK
+9itS0uX7GaitAgMBAAECggEBAIp+VpVku++If/1EnOisLJ3HfSGYpWcnswhZoqrGY24Fw/AN1pWP
+jZiwxGDNOADkBTze6C78KHef3GklNZJ63Ch8iH/toTzARdHoywcqpkj48/dqKizMeK7wWb9zVQKQ
+Uzy72e8rLNofowuF/qkYdzNGooEJzKwDUi+SPck16omrRgJoPd2A8WQC4Fjib7dd8uyP8iDwUYn0
+c4IGWULuKI+mEpE2QXR+wp1aXoJxT0TayyKBHweDzmcLpCpJ77XojHN8ZaEvgRDz+a2i/UVRQe9B
+NBIInIrgCa+D6YTfjVl2ApLstmcmp/mKId0r3ca5aII46GehTjRsXyb+38cY/60CgYEA4I83rtDt
+yMGfkVzHn9og8faYzMafCQW3WGVJ/4aIb+yM08+q+IqmtAcAv9qjnNvsUJDFqZVeSlxMlrq49qA/
+HV9WTc3zepmRdTH7wrFxs8ragW9krIj4Y9rEb47SyL2FzmXzXnMj9SXVWpnY7qjG1Ykobo+dRwGY
+TVbB/U/7Cn8CgYEAvNQg42rkXn/DXEPsdAQ2bdRh8a+2tCPcSkzk9wvhocBuk52XdFQuNouq5wjy
+83JayBQV1jNP9hFiZppPuraVzMtiY76ZOSST+houUga4/sh8oD4uJRPmFAv5H9XuYsFZpbSzZXtr
+562zCxUPN0ssDrE4c+TkHPTaiSlzzWY6/tMCgYBlezON1Ctxa1ciSQyJx/jVgDyjZite1295CiU7
+zd+AvSUTX6kDMx2NBBEporQH4jdUXWiGb9Mxxa5y+6U1B0weiQQmmykqQZZDoTgGT0x0FPtUPTQA
+6NFfxvC4/ZFyWHvMv7QQ/fXFBrj5fcdUa3+X5qkX9dz8xtK+OLPoNynbHwKBgQCHhcfE8KbOm+ve
+gHFoIs3drZxOFcqPJ12nheCe3kwmBzJVh7l3qCMyyrLx9h5IUz6Mcr3pahJtjLSO5xlp7Dk/LomD
+BPx7YqFB0yCDhoendMTdTUNZIRr0MFOwYZ4iCpsIrtRCdX5QXP4vagHtsWoBcXgO1axSi/l8j9+o
+/0JAOQKBgBu9iMX0tZNBoGW4Z0NABtr5xF9nsutbfXPFpcoAUZI/g1eL3GXCpVi/Q5Ztzzh7m3xb
+8LmeAiCNbQseUOi4r8aO54jmSaCam0EIZuTKpGMzxL5aHZK2wsouLVF1hA7+vI7Fa6QoHiwUuoXV
+5i2PPk0BHFjPDbIhhpGgUIkiQRom
+-----END PRIVATE KEY-----


Mime
View raw message