You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2018/04/26 15:13:36 UTC

[1/8] tomee git commit: Implement mp-jwt (first shoot)

Repository: tomee
Updated Branches:
  refs/heads/fb_tomee8 f3c5c2d6e -> 6d591bbbd


Implement mp-jwt (first shoot)


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

Branch: refs/heads/fb_tomee8
Commit: 82670f9b43a63ed28ac23ea9ec57846bcb8884e9
Parents: 58a3fa7
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Apr 17 22:31:11 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Apr 17 22:31:11 2018 +0200

----------------------------------------------------------------------
 .../core/security/AbstractSecurityService.java  | 12 ++++--
 pom.xml                                         |  1 +
 .../rs/event/ExtensionProviderRegistration.java |  4 +-
 .../tomee/microprofile/jwt/TCKTokenParser.java  | 40 ++++++++++++++++++++
 ...lipse.microprofile.jwt.tck.util.ITokenParser |  1 +
 tck/microprofile-tck/pom.xml                    |  1 +
 .../tomee/catalina/TomcatSecurityService.java   | 21 ++++++++++
 tomee/tomee-microprofile-webapp/pom.xml         | 16 ++++++++
 8 files changed, 91 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
index 57e2c9c..233db15 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
@@ -151,15 +151,17 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
         final String moduleID = newContext.getBeanContext().getModuleID();
         JavaSecurityManagers.setContextID(moduleID);
 
+        final SecurityContext defaultSecurityContext = getDefaultSecurityContext();
+
         final ProvidedSecurityContext providedSecurityContext = newContext.get(ProvidedSecurityContext.class);
         SecurityContext securityContext = oldContext != null ? oldContext.get(SecurityContext.class) :
-            (providedSecurityContext != null ? providedSecurityContext.context : null);
-        if (providedSecurityContext == null && (securityContext == null || securityContext == defaultContext)) {
+                (providedSecurityContext != null ? providedSecurityContext.context : null);
+        if (providedSecurityContext == null && (securityContext == null || securityContext == defaultSecurityContext)) {
             final Identity identity = clientIdentity.get();
             if (identity != null) {
                 securityContext = new SecurityContext(identity.subject);
             } else {
-                securityContext = defaultContext;
+                securityContext = defaultSecurityContext;
             }
         }
 
@@ -398,6 +400,10 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
         }
     }
 
+    protected SecurityContext getDefaultSecurityContext() {
+        return defaultContext;
+    }
+
     public static final class ProvidedSecurityContext {
         public final SecurityContext context;
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 53ded49..82b50dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -506,6 +506,7 @@
         <module>gradle</module>
         <module>container</module>
         <module>server</module>
+        <module>mp-jwt</module>
         <module>examples</module>
         <module>assembly</module>
         <module>tck</module>

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
index cfae25c..932a6bf 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
@@ -28,9 +28,9 @@ public class ExtensionProviderRegistration {
     private final List<Object> providers;
     private final AppContext appContext;
 
-    public ExtensionProviderRegistration(final AppContext ctx, final List<Object> existings) {
+    public ExtensionProviderRegistration(final AppContext ctx, final List<Object> providers) {
         this.appContext = ctx;
-        this.providers = existings;
+        this.providers = providers;
     }
 
     public AppContext getAppContext() {

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
new file mode 100644
index 0000000..ae563ec
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -0,0 +1,40 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory;
+import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+import org.eclipse.microprofile.jwt.tck.util.ITokenParser;
+
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * MP-JWT TCK harness class to parse a token string
+ */
+public class TCKTokenParser implements ITokenParser {
+
+    @Override
+    public JsonWebToken parse(final String bearerToken, final String issuer, final PublicKey publicKey) throws Exception {
+        final JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer);
+        final JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance();
+        return factory.parse(bearerToken, authContextInfo);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
new file mode 100644
index 0000000..4dcc059
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.TCKTokenParser
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/tck/microprofile-tck/pom.xml
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/pom.xml b/tck/microprofile-tck/pom.xml
index c48b7c5..9726358 100644
--- a/tck/microprofile-tck/pom.xml
+++ b/tck/microprofile-tck/pom.xml
@@ -32,6 +32,7 @@
 
   <modules>
     <module>config</module>
+    <module>jwt</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
index 81bffd4..e0e77be 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
@@ -39,6 +39,7 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.Callable;
 
 public class TomcatSecurityService extends AbstractSecurityService {
     private static final boolean ONLY_DEFAULT_REALM = "true".equals(SystemInstance.get().getProperty("tomee.realm.only-default", "false"));
@@ -330,4 +331,24 @@ public class TomcatSecurityService extends AbstractSecurityService {
         }
     }
 
+    @Override
+    protected SecurityContext getDefaultSecurityContext() {
+        final Request request = OpenEJBSecurityListener.requests.get();
+        if (request != null) {
+            final Object subjectCallable = request.getAttribute("javax.security.auth.subject.callable");
+            if (subjectCallable != null && Callable.class.isInstance(subjectCallable)) {
+                // maybe we should check, but it's so specific ...
+                try {
+                    final Subject subject = (Subject) Callable.class.cast(subjectCallable).call();
+                    return new SecurityContext(subject);
+
+                } catch (final Exception e) {
+                    // ignore and let it go to the default implementation
+                }
+            }
+        }
+
+        return super.getDefaultSecurityContext();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/82670f9b/tomee/tomee-microprofile-webapp/pom.xml
----------------------------------------------------------------------
diff --git a/tomee/tomee-microprofile-webapp/pom.xml b/tomee/tomee-microprofile-webapp/pom.xml
index 927bafe..c5f56ce 100644
--- a/tomee/tomee-microprofile-webapp/pom.xml
+++ b/tomee/tomee-microprofile-webapp/pom.xml
@@ -39,6 +39,9 @@
 
     <microprofile.config.api.version>1.3-SNAPSHOT</microprofile.config.api.version>
     <microprofile.config.impl.version>1.2-SNAPSHOT</microprofile.config.impl.version>
+
+    <microprofile.jwt.api.version>1.1-SNAPSHOT</microprofile.jwt.api.version>
+    <microprofile.jwt.impl.version>${project.version}</microprofile.jwt.impl.version>
   </properties>
 
   <dependencies>
@@ -60,6 +63,19 @@
       <artifactId>geronimo-config-impl</artifactId>
       <version>${microprofile.config.impl.version}</version>
     </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.microprofile.jwt</groupId>
+      <artifactId>microprofile-jwt-auth-api</artifactId>
+      <version>${microprofile.jwt.api.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mp-jwt</artifactId>
+      <version>${microprofile.jwt.impl.version}</version>
+    </dependency>
+
   </dependencies>
 
   <build>


[4/8] tomee git commit: Make a simple test case to wire up everything and start adding a simple UI on top

Posted by jl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
new file mode 100644
index 0000000..73a57f1
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
@@ -0,0 +1,62 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/templates', 'app/js/i18n', 'lib/backbone'];
+    define(deps, function (templates) {
+
+        var View = Backbone.View.extend({
+            el: 'body',
+
+            showView: function (view) {
+                var me = this;
+                var contentarea = me.$('.ux-contentarea');
+                if (me.currentView) {
+                    me.currentView.$el.detach();
+                }
+                me.currentView = view;
+                me.currentView.render();
+                contentarea.append(me.currentView.el);
+                if (view.renderCallback) {
+                    view.renderCallback();
+                }
+                me.$('.ux-app-menu-item').removeClass('active');
+                var myMenuItem = me.$('li.ux-app-menu-item.' + view.className);
+                myMenuItem.addClass('active');
+            },
+
+            render: function () {
+                if (this.options.isRendered) {
+                    return this;
+                }
+                var html = templates.getValue('container', {
+                    userName: ''
+                });
+                this.$el.html(html);
+
+                // render it only once
+                this.options.isRendered = true;
+                return this;
+            }
+        });
+
+        return new View({});
+    });
+}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
new file mode 100644
index 0000000..0417945
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
@@ -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
+ *
+ *     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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/templates', 'lib/underscore', 'lib/backbone', 'app/js/id'];
+    define(deps, function (templates, underscore) {
+
+        var View = Backbone.View.extend({
+            tagName: 'div',
+            className: 'modal ux-movie-window',
+            events: {
+                'click .ux-application': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('show-application', {});
+                },
+                'click .ux-close': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.remove();
+                },
+                'click .ux-save': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    var model = me.model;
+
+                    function set(name) {
+                        var field = $(me.$el.find('.ux-' + name).get(0));
+                        model.set(name, field.val());
+                    }
+
+                    set('title');
+                    set('director');
+                    set('genre');
+                    set('rating');
+                    set('year');
+                    me.trigger('save-model', {
+                        model: model
+                    });
+                }
+            },
+            render: function () {
+                var me = this;
+                me.$el.empty();
+                me.$el.append(templates.getValue('movie', {
+                    title: me.model.get('title'),
+                    director: me.model.get('director'),
+                    genre: me.model.get('genre'),
+                    rating: me.model.get('rating'),
+                    year: me.model.get('year'),
+                    currentYear: new Date().getFullYear()
+                }));
+                return me;
+            }
+        });
+        return View;
+    });
+}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/index.jsp b/examples/rest-mp-jwt/src/main/webapp/index.jsp
new file mode 100644
index 0000000..63d3e42
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/index.jsp
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title>Moviefun</title>
+  <link href="<c:url value='/webjars/bootstrap/3.1.0/css/bootstrap.min.css'/>" rel="stylesheet">
+  <link href="<c:url value='/app/app.less'/>" rel="stylesheet/less" type="text/css">
+  <script src="<c:url value='/webjars/requirejs/2.1.10/require.min.js'/>"></script>
+  <script type="text/javascript">
+    window.ux = window.ux || {};
+    window.ux.SESSION_ID = "<%=request.getSession().getId()%>";
+    window.ux.ROOT_URL = "<c:url value='/'/>".replace(';jsessionid=' + window.ux.SESSION_ID, '');
+  </script>
+  <script src="<c:url value='/app/config.js'/>"></script>
+  <script src="<c:url value='/app/js/start.js'/>"></script>
+</head>
+<body></body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java b/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java
new file mode 100644
index 0000000..b18e64e
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/MoviesTest.java
@@ -0,0 +1,88 @@
+/**
+ * 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;
+
+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.ClassLoaderAsset;
+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.LoadRest;
+import org.superbiz.moviefun.rest.MoviesMPJWTConfigurationProvider;
+import org.superbiz.moviefun.rest.MoviesRest;
+import org.superbiz.rest.GreetingService;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashMap;
+
+import static java.util.Collections.singletonList;
+
+@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, LoadRest.class)
+                .addClasses(MoviesRest.class, GreetingService.class, ApplicationConfig.class)
+                .addClass(MoviesMPJWTConfigurationProvider.class)
+                .addAsWebInfResource(new StringAsset("<beans/>"), "beans.xml")
+                .addAsResource(new ClassLoaderAsset("META-INF/persistence.xml"), "META-INF/persistence.xml");
+
+        System.out.println(webArchive.toString(true));
+
+        return webArchive;
+    }
+
+    @ArquillianResource
+    private URL base;
+
+    @Test
+    public void sthg() throws Exception {
+
+        final WebClient webClient = WebClient
+                .create(base.toExternalForm(), singletonList(new JohnzonProvider<>()), singletonList(new LoggingFeature()), null);
+
+        webClient
+                .reset()
+                .path("/rest/greeting/")
+                .get(String.class);
+
+        final Collection<? extends Movie> movies = webClient
+                .reset()
+                .path("/rest/movies/")
+                .header("Authorization", "Bearer " + token())
+                .getCollection(Movie.class);
+
+        System.out.println(movies);
+    }
+
+    private String token() throws Exception {
+        HashMap<String, Long> timeClaims = new HashMap<>();
+        return TokenUtils.generateTokenString("/Token1.json", null, timeClaims);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java b/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java
new file mode 100644
index 0000000..5aa34b4
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/java/org/superbiz/moviefun/TokenUtils.java
@@ -0,0 +1,257 @@
+/*
+ * 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
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/java/org/superbiz/rest/GreetingServiceTest.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/java/org/superbiz/rest/GreetingServiceTest.java b/examples/rest-mp-jwt/src/test/java/org/superbiz/rest/GreetingServiceTest.java
new file mode 100644
index 0000000..f38063f
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/java/org/superbiz/rest/GreetingServiceTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.rest;
+
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.core.MediaType;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices(value = "jaxrs", httpDebug = true)
+@RunWith(ApplicationComposer.class)
+public class GreetingServiceTest {
+
+    @Module
+    @Classes(GreetingService.class)
+    public WebApp app() {
+        return new WebApp().contextRoot("test");
+    }
+
+    @Test
+    public void get() throws IOException {
+        final String message = WebClient.create("http://localhost:4204")
+                .path("/test/greeting/")
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(String.class);
+        assertEquals("Hi Microprofile JWT!", message);
+    }
+
+    @Test
+    public void post() throws IOException {
+        final String message = WebClient.create("http://localhost:4204")
+                .path("/test/greeting/")
+                .type(MediaType.APPLICATION_JSON_TYPE)
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .post("Hi REST!", String.class);
+        assertEquals("hi rest!", message);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/META-INF/application-client.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/META-INF/application-client.xml b/examples/rest-mp-jwt/src/test/resources/META-INF/application-client.xml
new file mode 100644
index 0000000..1e91dca
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/META-INF/application-client.xml
@@ -0,0 +1 @@
+<application-client/>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/Token1.json
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/Token1.json b/examples/rest-mp-jwt/src/test/resources/Token1.json
new file mode 100644
index 0000000..32b03c8
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/Token1.json
@@ -0,0 +1,20 @@
+{
+    "iss": "https://server.example.com",
+    "jti": "a-123",
+    "sub": "24400320",
+    "upn": "jdoe@example.com",
+    "preferred_username": "jdoe",
+    "aud": "s6BhdRkqt3",
+    "exp": 1311281970,
+    "iat": 1311280970,
+    "auth_time": 1311280969,
+    "roles": [
+        "Echoer"
+    ],
+    "groups": [
+        "Echoer",
+        "Tester",
+        "group1",
+        "group2"
+    ]
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/Token2.json
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/Token2.json b/examples/rest-mp-jwt/src/test/resources/Token2.json
new file mode 100644
index 0000000..d69f61a
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/Token2.json
@@ -0,0 +1,12 @@
+{
+  "iss": "https://server.example.com",
+  "jti": "a-123.2",
+  "sub": "24400320#2",
+  "upn": "jdoe2@example.com",
+  "preferred_username": "jdoe",
+  "aud": "s6BhdRkqt3.2",
+  "exp": 1311281970,
+  "iat": 1311280970,
+  "auth_time": 1311280969,
+  "groups": ["Echoer2", "Tester", "Token2Role", "group1.2", "group2.2"]
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/arquillian.xml b/examples/rest-mp-jwt/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..4744e7a
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/arquillian.xml
@@ -0,0 +1,32 @@
+<?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

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/privateKey.pem
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/privateKey.pem b/examples/rest-mp-jwt/src/test/resources/privateKey.pem
new file mode 100644
index 0000000..e20d80b
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/privateKey.pem
@@ -0,0 +1,28 @@
+-----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-----

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/test/resources/publicKey.pem
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/test/resources/publicKey.pem b/examples/rest-mp-jwt/src/test/resources/publicKey.pem
new file mode 100644
index 0000000..a1dc20c
--- /dev/null
+++ b/examples/rest-mp-jwt/src/test/resources/publicKey.pem
@@ -0,0 +1,9 @@
+-----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-----

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 051f05a..ca69b0a 100644
--- a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -18,7 +18,6 @@ package org.apache.tomee.microprofile.jwt.cdi;
 
 import org.apache.tomee.microprofile.jwt.MPJWTFilter;
 import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
-import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
 import org.eclipse.microprofile.jwt.Claim;
 
 import javax.enterprise.event.Observes;
@@ -37,24 +36,13 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 public class MPJWTCDIExtension implements Extension {
 
-    private static final Predicate<InjectionPoint> NOT_PROVIDERS = new Predicate<InjectionPoint>() {
-        @Override
-        public boolean test(final InjectionPoint ip) {
-            return (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Provider.class);
-        }
-    };
-    private static final Predicate<InjectionPoint> NOT_INSTANCES = new Predicate<InjectionPoint>() {
-        @Override
-        public boolean test(final InjectionPoint ip) {
-            return (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Instance.class);
-        }
-    };
+    private static final Predicate<InjectionPoint> NOT_PROVIDERS = ip -> (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Provider.class);
+    private static final Predicate<InjectionPoint> NOT_INSTANCES = ip -> (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Instance.class);
     private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>();
 
     static {
@@ -79,44 +67,24 @@ public class MPJWTCDIExtension implements Extension {
         final Set<Type> types = injectionPoints.stream()
                 .filter(NOT_PROVIDERS)
                 .filter(NOT_INSTANCES)
-                .map(new Function<InjectionPoint, Type>() {
-                    @Override
-                    public Type apply(final InjectionPoint ip) {
-                        return REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType());
-                    }
-                })
+                .map(ip -> REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType()))
                 .collect(Collectors.<Type>toSet());
 
         final Set<Type> providerTypes = injectionPoints.stream()
                 .filter(NOT_PROVIDERS.negate())
-                .map(new Function<InjectionPoint, Type>() {
-                    @Override
-                    public Type apply(final InjectionPoint ip) {
-                        return ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
-                    }
-                })
+                .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
                 .collect(Collectors.<Type>toSet());
 
         final Set<Type> instanceTypes = injectionPoints.stream()
                 .filter(NOT_INSTANCES.negate())
-                .map(new Function<InjectionPoint, Type>() {
-                    @Override
-                    public Type apply(final InjectionPoint ip) {
-                        return ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
-                    }
-                })
+                .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
                 .collect(Collectors.<Type>toSet());
 
         types.addAll(providerTypes);
         types.addAll(instanceTypes);
 
         types.stream()
-                .map(new Function<Type, ClaimBean>() {
-                    @Override
-                    public ClaimBean apply(final Type type) {
-                        return new ClaimBean<>(bm, type);
-                    }
-                })
+                .map(type -> new ClaimBean<>(bm, type))
                 .forEach(new Consumer<ClaimBean>() {
                     @Override
                     public void accept(final ClaimBean claimBean) {
@@ -129,7 +97,6 @@ public class MPJWTCDIExtension implements Extension {
         bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
         bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
         bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
-        bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
         bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
     }
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
deleted file mode 100644
index 9247e04..0000000
--- a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.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.apache.tomee.microprofile.jwt.config;
-
-import javax.enterprise.context.Dependent;
-import javax.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 JWTAuthContextInfoProvider {
-
-    @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();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java b/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
new file mode 100644
index 0000000..bf0a07f
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
@@ -0,0 +1,63 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+
+import javax.enterprise.context.Dependent;
+import javax.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 JWTAuthContextInfoProvider {
+
+    @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();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
index cf4e837..f5f2183 100644
--- a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
+++ b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
@@ -68,7 +68,8 @@ public class AppDeploymentExtension implements LoadableExtension {
             if (!(appArchive instanceof WebArchive)) {
                 return;
             }
-            WebArchive war = WebArchive.class.cast(appArchive);
+            final WebArchive war = WebArchive.class.cast(appArchive);
+            war.addClass(JWTAuthContextInfoProvider.class);
 
             log.info("Augmented war: \n"+war.toString(true));
         }


[3/8] tomee git commit: Missing files from previous commit

Posted by jl...@apache.org.
Missing files from previous commit


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

Branch: refs/heads/fb_tomee8
Commit: def443a4174a402ee25a30325d4695c5c995b2ac
Parents: 82670f9
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Apr 17 22:31:41 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Apr 17 22:31:41 2018 +0200

----------------------------------------------------------------------
 mp-jwt/pom.xml                                  |  79 ++++
 .../tomee/microprofile/jwt/MPJWTFilter.java     | 271 ++++++++++++++
 .../microprofile/jwt/MPJWTInitializer.java      |  64 ++++
 .../tomee/microprofile/jwt/ParseException.java  |  32 ++
 .../tomee/microprofile/jwt/cdi/ClaimBean.java   | 373 +++++++++++++++++++
 .../jwt/cdi/ClaimInjectionPoint.java            |  70 ++++
 .../microprofile/jwt/cdi/ClaimValueWrapper.java |  53 +++
 .../microprofile/jwt/cdi/DefaultLiteral.java    |  24 ++
 .../microprofile/jwt/cdi/JsonbProducer.java     |  46 +++
 .../microprofile/jwt/cdi/MPJWTCDIExtension.java | 136 +++++++
 .../microprofile/jwt/cdi/MPJWTProducer.java     |  49 +++
 .../jwt/config/JWTAuthContextInfo.java          |  67 ++++
 .../jwt/config/JWTAuthContextInfoProvider.java  |  61 +++
 .../jwt/jaxrs/MPJWPProviderRegistration.java    |  36 ++
 .../MPJWTSecurityAnnotationsInterceptor.java    |  57 +++
 ...TSecurityAnnotationsInterceptorsFeature.java | 144 +++++++
 .../principal/DefaultJWTCallerPrincipal.java    | 360 ++++++++++++++++++
 .../DefaultJWTCallerPrincipalFactory.java       |  92 +++++
 .../jwt/principal/JWTCallerPrincipal.java       |  59 +++
 .../principal/JWTCallerPrincipalFactory.java    | 129 +++++++
 .../META-INF/org.apache.openejb.extension       |   1 +
 .../javax.enterprise.inject.spi.Extension       |   1 +
 .../javax.servlet.ServletContainerInitializer   |   1 +
 ...file.jwt.principal.JWTCallerPrincipalFactory |   1 +
 tck/microprofile-tck/jwt/pom.xml                | 197 ++++++++++
 .../jwt/AppDeploymentExtension.java             |  76 ++++
 ....jboss.arquillian.core.spi.LoadableExtension |   1 +
 .../jwt/src/test/resources/arquillian.xml       |  39 ++
 .../jwt/src/test/resources/dev.xml              |  93 +++++
 29 files changed, 2612 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/mp-jwt/pom.xml b/mp-jwt/pom.xml
new file mode 100644
index 0000000..a6cae6a
--- /dev/null
+++ b/mp-jwt/pom.xml
@@ -0,0 +1,79 @@
+<?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">
+  <parent>
+    <artifactId>tomee-project</artifactId>
+    <groupId>org.apache.tomee</groupId>
+    <version>8.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>mp-jwt</artifactId>
+  <packaging>jar</packaging>
+  <name>OpenEJB :: Microprofile JWT</name>
+
+  <properties>
+    <mp-jwt.version>1.1-SNAPSHOT</mp-jwt.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomee</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>${version.javaee-api}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openejb-core</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openejb-cxf-rs</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.bitbucket.b_c</groupId>
+      <artifactId>jose4j</artifactId>
+      <version>0.6.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.johnzon</groupId>
+      <artifactId>johnzon-jsonb</artifactId>
+      <version>${johnzon.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-catalina</artifactId>
+      <version>${tomcat.version}</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>
+  </dependencies>
+
+
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
new file mode 100644
index 0000000..a7b47d3
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -0,0 +1,271 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.inject.Inject;
+import javax.security.auth.Subject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+// async is supported because we only need to do work on the way in
+@WebFilter(asyncSupported = true, urlPatterns = "/*")
+public class MPJWTFilter implements Filter {
+
+    @Inject
+    private JWTAuthContextInfo authContextInfo;
+
+    @Override
+    public void init(final FilterConfig filterConfig) throws ServletException {
+        // nothing so far
+
+    }
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+
+        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+
+        // now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
+        try {
+            chain.doFilter(new MPJWTServletRequestWrapper(httpServletRequest, authContextInfo), response);
+
+        } catch (final Exception e) {
+            // this is an alternative to the @Provider bellow which requires registration on the fly
+            // or users to add it into their webapp for scanning or into the Application itself
+            if (MPJWTException.class.isInstance(e)) {
+                final MPJWTException jwtException = MPJWTException.class.cast(e);
+                HttpServletResponse.class.cast(response).sendError(jwtException.getStatus(), jwtException.getMessage());
+            }
+
+            if (MPJWTException.class.isInstance(e.getCause())) {
+                final MPJWTException jwtException = MPJWTException.class.cast(e.getCause());
+                HttpServletResponse.class.cast(response).sendError(jwtException.getStatus(), jwtException.getMessage());
+            }
+
+        }
+
+    }
+
+    @Override
+    public void destroy() {
+        // nothing to do
+    }
+
+    private static Function<HttpServletRequest, JsonWebToken> token(final HttpServletRequest httpServletRequest, final JWTAuthContextInfo authContextInfo) {
+
+        return new Function<HttpServletRequest, JsonWebToken>() {
+
+            private JsonWebToken jsonWebToken;
+
+            @Override
+            public JsonWebToken apply(final HttpServletRequest request) {
+
+                // not sure it's worth having synchronization inside a single request
+                // worth case, we would parse and validate the token twice
+                if (jsonWebToken != null) {
+                    return jsonWebToken;
+                }
+
+                final String authorizationHeader = httpServletRequest.getHeader("Authorization");
+                if (authorizationHeader == null || authorizationHeader.isEmpty()) {
+                    throw new MissingAuthorizationHeaderException();
+                }
+
+                if (!authorizationHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer ")) {
+                    throw new BadAuthorizationPrefixException(authorizationHeader);
+                }
+
+                final String token = authorizationHeader.substring("bearer ".length());
+                try {
+                    jsonWebToken = validate(token, authContextInfo);
+
+                } catch (final ParseException e) {
+                    throw new InvalidTokenException(token, e);
+                }
+
+                return jsonWebToken;
+
+            }
+        };
+
+    }
+
+    private static JsonWebToken validate(final String bearerToken, final JWTAuthContextInfo authContextInfo) throws ParseException {
+        JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
+        return factory.parse(bearerToken, authContextInfo);
+    }
+
+    public static class MPJWTServletRequestWrapper extends HttpServletRequestWrapper {
+
+        private final Function<HttpServletRequest, JsonWebToken> tokenFunction;
+        private final HttpServletRequest request;
+
+        /**
+         * Constructs a request object wrapping the given request.
+         *
+         * @param request         The request to wrap
+         * @param authContextInfo the context configuration to validate the token
+         * @throws IllegalArgumentException if the request is null
+         */
+        public MPJWTServletRequestWrapper(final HttpServletRequest request, final JWTAuthContextInfo authContextInfo) {
+            super(request);
+            this.request = request;
+            tokenFunction = token(request, authContextInfo);
+
+            // this is so that the MPJWTProducer can find the function and apply it if necessary
+            request.setAttribute(JsonWebToken.class.getName(), tokenFunction);
+            request.setAttribute("javax.security.auth.subject.callable", (Callable<Subject>) new Callable<Subject>() {
+                @Override
+                public Subject call() throws Exception {
+                    final Set<Principal> principals = new LinkedHashSet<>();
+                    final JsonWebToken namePrincipal = tokenFunction.apply(request);
+                    principals.add(namePrincipal);
+                    principals.addAll(namePrincipal.getGroups().stream().map(new Function<String, Principal>() {
+                        @Override
+                        public Principal apply(final String role) {
+                            return (Principal) new Principal() {
+                                @Override
+                                public String getName() {
+                                    return role;
+                                }
+                            };
+                        }
+                    }).collect(Collectors.<Principal>toList()));
+                    return new Subject(true, principals, Collections.emptySet(), Collections.emptySet());
+                }
+            });
+        }
+
+        @Override
+        public Principal getUserPrincipal() {
+            return tokenFunction.apply(request);
+        }
+
+        @Override
+        public boolean isUserInRole(String role) {
+            final JsonWebToken jsonWebToken = tokenFunction.apply(request);
+            return jsonWebToken.getGroups().contains(role);
+        }
+
+        @Override
+        public String getAuthType() {
+            return "MP-JWT";
+        }
+
+    }
+
+    private static abstract class MPJWTException extends RuntimeException {
+
+        public MPJWTException() {
+            super();
+        }
+
+        public MPJWTException(final Throwable cause) {
+            super(cause);
+        }
+
+        public abstract int getStatus();
+
+        public abstract String getMessage();
+    }
+
+    private static class MissingAuthorizationHeaderException extends MPJWTException {
+
+        @Override
+        public int getStatus() {
+            return HttpServletResponse.SC_UNAUTHORIZED;
+        }
+
+        @Override
+        public String getMessage() {
+            return "No authorization header provided. Can't validate the JWT.";
+        }
+    }
+
+    private static class BadAuthorizationPrefixException extends MPJWTException {
+
+        private String authorizationHeader;
+
+        public BadAuthorizationPrefixException(final String authorizationHeader) {
+            this.authorizationHeader = authorizationHeader;
+        }
+
+        @Override
+        public int getStatus() {
+            return HttpServletResponse.SC_UNAUTHORIZED;
+        }
+
+        @Override
+        public String getMessage() {
+            return "Authorization header does not use the Bearer prefix. Can't validate header " + authorizationHeader;
+        }
+    }
+
+    private static class InvalidTokenException extends MPJWTException {
+
+        private final String token;
+
+        public InvalidTokenException(final String token, final Throwable cause) {
+            super(cause);
+            this.token = token;
+        }
+
+        @Override
+        public int getStatus() {
+            return HttpServletResponse.SC_UNAUTHORIZED;
+        }
+
+        @Override
+        public String getMessage() {
+            return "Invalid or not parsable JWT " + token; // we might want to break down the exceptions so we can have more messages.
+        }
+    }
+
+    @Provider // would be the ideal but not automatically registered
+    public static class MPJWTExceptionMapper implements ExceptionMapper<MPJWTException> {
+
+        @Override
+        public Response toResponse(final MPJWTException exception) {
+            return Response.status(exception.getStatus()).entity(exception.getMessage()).build();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
new file mode 100644
index 0000000..cede7dc
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -0,0 +1,64 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.HandlesTypes;
+import javax.ws.rs.core.Application;
+import java.util.Set;
+
+/**
+ * Responsible for adding the filter into the chain and doing all other initialization
+ */
+@HandlesTypes(LoginConfig.class)
+public class MPJWTInitializer implements ServletContainerInitializer {
+
+    @Override
+    public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
+
+        if (classes == null || classes.isEmpty()) {
+            return; // no classe having @LoginConfig on it
+        }
+
+        for (Class<?> clazz : classes) {
+            final LoginConfig loginConfig = clazz.getAnnotation(LoginConfig.class);
+
+            if (loginConfig.authMethod() == null && !"MP-JWT".equals(loginConfig.authMethod())) {
+                continue;
+            }
+
+            if (!Application.class.isAssignableFrom(clazz)) {
+                continue;
+                // do we really want Application?
+                // See https://github.com/eclipse/microprofile-jwt-auth/issues/70 to clarify this point
+            }
+
+            final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
+            mpJwtFilter.setAsyncSupported(true);
+            mpJwtFilter.addMappingForUrlPatterns(null, false, "/*");
+
+            break; // no need to add it more than once
+        }
+
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
new file mode 100644
index 0000000..d9572d5
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
@@ -0,0 +1,32 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt;
+
+/**
+ * The exception thrown when
+ */
+public class ParseException extends Exception {
+    private static final long serialVersionUID = 1L;
+
+    public ParseException(final String message) {
+        super(message);
+    }
+
+    public ParseException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
new file mode 100644
index 0000000..be83a9b
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -0,0 +1,373 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.Vetoed;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonValue;
+import javax.json.bind.Jsonb;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+@Vetoed
+public class ClaimBean<T> implements Bean<T>, PassivationCapable {
+
+    private static final Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
+    private static final Set<Annotation> QUALIFIERS = new HashSet<>();
+
+    static {
+        QUALIFIERS.add(new ClaimLiteral());
+    }
+
+    @Inject
+    private Jsonb jsonb;
+
+    private final BeanManager bm;
+    private final Class rawType;
+    private final Set<Type> types;
+    private final String id;
+    private final Class<? extends Annotation> scope;
+
+    public ClaimBean(final BeanManager bm, final Type type) {
+        this.bm = bm;
+        types = new HashSet<>();
+        types.add(type);
+        rawType = getRawType(type);
+        this.id = "ClaimBean_" + types;
+        scope = Dependent.class;
+    }
+
+    private Class getRawType(final Type type) {
+        if (Class.class.isInstance(type)) {
+            return Class.class.cast(type);
+
+        } else if (ParameterizedType.class.isInstance(type)) {
+            final ParameterizedType paramType = ParameterizedType.class.cast(type);
+            return Class.class.cast(paramType.getRawType());
+        }
+
+        throw new UnsupportedOperationException("Unsupported type " + type);
+    }
+
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Class<?> getBeanClass() {
+        return rawType;
+    }
+
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+
+    @Override
+    public void destroy(final T instance, final CreationalContext<T> context) {
+        logger.finest("Destroying CDI Bean for type " + types.iterator().next());
+    }
+
+    @Override
+    public Set<Type> getTypes() {
+        return types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers() {
+        return QUALIFIERS;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return scope;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isAlternative() {
+        return false;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public T create(final CreationalContext<T> context) {
+        logger.finest("Creating CDI Bean for type " + types.iterator().next());
+        final InjectionPoint ip = (InjectionPoint) bm.getInjectableReference(new ClaimInjectionPoint(this), context);
+        if (ip == null) {
+            throw new IllegalStateException("Could not retrieve InjectionPoint for type " + types.iterator().next());
+        }
+
+        final Annotated annotated = ip.getAnnotated();
+        final Claim claim = annotated.getAnnotation(Claim.class);
+        final String key = getClaimKey(claim);
+
+        logger.finest(String.format("Found Claim injection with name=%s and for %s", key, ip.toString()));
+
+        if (ParameterizedType.class.isInstance(annotated.getBaseType())) {
+            final ParameterizedType paramType = ParameterizedType.class.cast(annotated.getBaseType());
+            final Type rawType = paramType.getRawType();
+            if (Class.class.isInstance(rawType) && paramType.getActualTypeArguments().length == 1) {
+
+                final Class<?> rawTypeClass = ((Class<?>) rawType);
+
+                // handle Provider<T>
+                if (rawTypeClass.isAssignableFrom(Provider.class)) {
+                    final Type providerType = paramType.getActualTypeArguments()[0];
+                    if (ParameterizedType.class.isInstance(providerType) && isOptional(ParameterizedType.class.cast(providerType))) {
+                        return (T) Optional.ofNullable(getClaimValue(key));
+                    }
+                    return getClaimValue(key);
+                }
+
+                // handle Instance<T>
+                if (rawTypeClass.isAssignableFrom(Instance.class)) {
+                    final Type instanceType = paramType.getActualTypeArguments()[0];
+                    if (ParameterizedType.class.isInstance(instanceType) && isOptional(ParameterizedType.class.cast(instanceType))) {
+                        return (T) Optional.ofNullable(getClaimValue(key));
+                    }
+                    return getClaimValue(key);
+                }
+
+                // handle ClaimValue<T>
+                if (rawTypeClass.isAssignableFrom(ClaimValue.class)) {
+                    final Type claimValueType = paramType.getActualTypeArguments()[0];
+
+                    final ClaimValueWrapper claimValueWrapper = new ClaimValueWrapper(key);
+                    if (ParameterizedType.class.isInstance(claimValueType) && isOptional(ParameterizedType.class.cast(claimValueType))) {
+                        claimValueWrapper.setValue(new Supplier() {
+                            @Override
+                            public Object get() {
+                                final T claimValue = ClaimBean.this.getClaimValue(key);
+                                return Optional.ofNullable(claimValue);
+                            }
+                        });
+
+                    } else if (ParameterizedType.class.isInstance(claimValueType) && isSet(ParameterizedType.class.cast(claimValueType))) {
+                        claimValueWrapper.setValue(new Supplier() {
+                            @Override
+                            public Object get() {
+                                final T claimValue = ClaimBean.this.getClaimValue(key);
+                                return claimValue;
+                            }
+                        });
+
+                    } else if (ParameterizedType.class.isInstance(claimValueType) && isList(ParameterizedType.class.cast(claimValueType))) {
+                        claimValueWrapper.setValue(new Supplier() {
+                            @Override
+                            public Object get() {
+                                final T claimValue = ClaimBean.this.getClaimValue(key);
+                                return claimValue;
+                            }
+                        });
+
+                    } else if (Class.class.isInstance(claimValueType)) {
+                        claimValueWrapper.setValue(new Supplier() {
+                            @Override
+                            public Object get() {
+                                final T claimValue = ClaimBean.this.getClaimValue(key);
+                                return claimValue;
+                            }
+                        });
+
+                    } else {
+                        throw new IllegalArgumentException("Unsupported ClaimValue type " + claimValueType.toString());
+                    }
+
+                    return (T) claimValueWrapper;
+                }
+
+                // handle Optional<T>
+                if (rawTypeClass.isAssignableFrom(Optional.class)) {
+                    return getClaimValue(key);
+                }
+
+                // handle Set<T>
+                if (rawTypeClass.isAssignableFrom(Set.class)) {
+                    return getClaimValue(key);
+                }
+
+                // handle List<T>
+                if (rawTypeClass.isAssignableFrom(List.class)) {
+                    return getClaimValue(key);
+                }
+            }
+
+        } else if (annotated.getBaseType().getTypeName().startsWith("javax.json.Json")) {
+            // handle JsonValue<T> (number, string, etc)
+            return (T) toJson(key);
+
+        } else {
+            // handle Raw types
+            return getClaimValue(key);
+        }
+
+        throw new IllegalStateException("Unhandled Claim type " + annotated.getBaseType());
+    }
+
+    public static String getClaimKey(final Claim claim) {
+        return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+    }
+
+    private T getClaimValue(final String name) {
+        final Bean<?> bean = bm.resolve(bm.getBeans(JsonWebToken.class));
+        JsonWebToken jsonWebToken = null;
+        if (RequestScoped.class.equals(bean.getScope())) {
+            jsonWebToken = JsonWebToken.class.cast(bm.getReference(bean, JsonWebToken.class, null));
+        }
+        if (jsonWebToken == null || !bean.getScope().equals(RequestScoped.class)) {
+            logger.warning(String.format("Can't retrieve claim %s. No active principal.", name));
+            return null;
+        }
+
+        final Optional<T> claimValue = jsonWebToken.claim(name);
+        logger.finest(String.format("Found ClaimValue=%s for name=%s", claimValue, name));
+        return claimValue.orElse(null);
+    }
+
+    private JsonValue toJson(final String name) {
+        final T claimValue = getClaimValue(name);
+        return wrapValue(claimValue);
+    }
+
+    private static final String TMP = "tmp";
+
+    private JsonValue wrapValue(final Object value) {
+        JsonValue jsonValue = null;
+
+        if (JsonValue.class.isInstance(value)) {
+            // This may already be a JsonValue
+            jsonValue = JsonValue.class.cast(value);
+
+        } else if (String.class.isInstance(value)) {
+            jsonValue = Json.createObjectBuilder()
+                    .add(TMP, value.toString())
+                    .build()
+                    .getJsonString(TMP);
+
+        } else if (Number.class.isInstance(value)) {
+            final Number number = Number.class.cast(value);
+            if ((Long.class.isInstance(number)) || (Integer.class.isInstance(number))) {
+                jsonValue = Json.createObjectBuilder()
+                        .add(TMP, number.longValue())
+                        .build()
+                        .getJsonNumber(TMP);
+
+            } else {
+                jsonValue = Json.createObjectBuilder()
+                        .add(TMP, number.doubleValue())
+                        .build()
+                        .getJsonNumber(TMP);
+            }
+
+        } else if (Boolean.class.isInstance(value)) {
+            final Boolean flag = Boolean.class.cast(value);
+            jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+
+        } else if (Collection.class.isInstance(value)) {
+            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+            final Collection list = Collection.class.cast(value);
+
+            for (Object element : list) {
+                if (String.class.isInstance(element)) {
+                    arrayBuilder.add(element.toString());
+
+                } else {
+                    final JsonValue jvalue = wrapValue(element);
+                    arrayBuilder.add(jvalue);
+                }
+            }
+            jsonValue = arrayBuilder.build();
+
+        } else if (Map.class.isInstance(value)) {
+            jsonValue = jsonb.fromJson(jsonb.toJson(value), JsonObject.class);
+
+        }
+        return jsonValue;
+    }
+
+    private boolean isOptional(final ParameterizedType type) {
+        return ((Class) type.getRawType()).isAssignableFrom(Optional.class);
+    }
+
+    private boolean isSet(final ParameterizedType type) {
+        return ((Class) type.getRawType()).isAssignableFrom(Set.class);
+    }
+
+    private boolean isList(final ParameterizedType type) {
+        return ((Class) type.getRawType()).isAssignableFrom(List.class);
+    }
+
+    private static class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
+
+        @Override
+        public String value() {
+            return "";
+        }
+
+        @Override
+        public Claims standard() {
+            return Claims.UNKNOWN;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
new file mode 100644
index 0000000..2f1fd3d
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
@@ -0,0 +1,70 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Set;
+
+public class ClaimInjectionPoint implements InjectionPoint {
+
+    private final Bean bean;
+
+    public ClaimInjectionPoint(final Bean bean) {
+        this.bean = bean;
+    }
+
+    @Override
+    public boolean isTransient() {
+        return false;
+    }
+
+    @Override
+    public boolean isDelegate() {
+        return false;
+    }
+
+    @Override
+    public Type getType() {
+        return InjectionPoint.class;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers() {
+        return Collections.<Annotation>singleton(DefaultLiteral.INSTANCE);
+    }
+
+    @Override
+    public Member getMember() {
+        return null;
+    }
+
+    @Override
+    public Bean<?> getBean() {
+        return bean;
+    }
+
+    @Override
+    public Annotated getAnnotated() {
+        return null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
new file mode 100644
index 0000000..2836abd
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
@@ -0,0 +1,53 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.ClaimValue;
+
+import java.util.function.Supplier;
+
+public class ClaimValueWrapper<T> implements ClaimValue<T> {
+
+    private final String name;
+    private Supplier<T> value;
+
+    public ClaimValueWrapper(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public T getValue() {
+        return value.get();
+    }
+
+    void setValue(final Supplier<T> value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "ClaimValueWrapper{" +
+                "name='" + name + '\'' +
+                ", value=" + value.get() +
+                '}';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
new file mode 100644
index 0000000..273ff96
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
@@ -0,0 +1,24 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.inject.Default;
+import javax.enterprise.util.AnnotationLiteral;
+
+public class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
+    public static final Default INSTANCE = new DefaultLiteral();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
new file mode 100644
index 0000000..53a9088
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
@@ -0,0 +1,46 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.json.bind.Jsonb;
+import javax.json.bind.spi.JsonbProvider;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@ApplicationScoped
+// todo add a qualifier here so we isolate our instance from what applications would do
+public class JsonbProducer {
+
+    private static final Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
+    @Produces
+    public Jsonb create() {
+        return JsonbProvider.provider().create().build();
+    }
+
+    public void close(@Disposes final Jsonb jsonb) {
+        try {
+            jsonb.close();
+
+        } catch (final Exception e) {
+            log.log(Level.WARNING, e.getMessage(), e);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
new file mode 100644
index 0000000..051f05a
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -0,0 +1,136 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import org.apache.tomee.microprofile.jwt.MPJWTFilter;
+import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
+import org.eclipse.microprofile.jwt.Claim;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.inject.Provider;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+public class MPJWTCDIExtension implements Extension {
+
+    private static final Predicate<InjectionPoint> NOT_PROVIDERS = new Predicate<InjectionPoint>() {
+        @Override
+        public boolean test(final InjectionPoint ip) {
+            return (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Provider.class);
+        }
+    };
+    private static final Predicate<InjectionPoint> NOT_INSTANCES = new Predicate<InjectionPoint>() {
+        @Override
+        public boolean test(final InjectionPoint ip) {
+            return (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Instance.class);
+        }
+    };
+    private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>();
+
+    static {
+        REPLACED_TYPES.put(double.class, Double.class);
+        REPLACED_TYPES.put(int.class, Integer.class);
+        REPLACED_TYPES.put(float.class, Float.class);
+        REPLACED_TYPES.put(long.class, Long.class);
+        REPLACED_TYPES.put(boolean.class, Boolean.class);
+    }
+
+    private Set<InjectionPoint> injectionPoints = new HashSet<>();
+
+    public void collectConfigProducer(@Observes final ProcessInjectionPoint<?, ?> pip) {
+        final Claim claim = pip.getInjectionPoint().getAnnotated().getAnnotation(Claim.class);
+        if (claim != null) {
+            injectionPoints.add(pip.getInjectionPoint());
+        }
+    }
+
+    public void registerClaimProducer(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
+
+        final Set<Type> types = injectionPoints.stream()
+                .filter(NOT_PROVIDERS)
+                .filter(NOT_INSTANCES)
+                .map(new Function<InjectionPoint, Type>() {
+                    @Override
+                    public Type apply(final InjectionPoint ip) {
+                        return REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType());
+                    }
+                })
+                .collect(Collectors.<Type>toSet());
+
+        final Set<Type> providerTypes = injectionPoints.stream()
+                .filter(NOT_PROVIDERS.negate())
+                .map(new Function<InjectionPoint, Type>() {
+                    @Override
+                    public Type apply(final InjectionPoint ip) {
+                        return ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
+                    }
+                })
+                .collect(Collectors.<Type>toSet());
+
+        final Set<Type> instanceTypes = injectionPoints.stream()
+                .filter(NOT_INSTANCES.negate())
+                .map(new Function<InjectionPoint, Type>() {
+                    @Override
+                    public Type apply(final InjectionPoint ip) {
+                        return ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
+                    }
+                })
+                .collect(Collectors.<Type>toSet());
+
+        types.addAll(providerTypes);
+        types.addAll(instanceTypes);
+
+        types.stream()
+                .map(new Function<Type, ClaimBean>() {
+                    @Override
+                    public ClaimBean apply(final Type type) {
+                        return new ClaimBean<>(bm, type);
+                    }
+                })
+                .forEach(new Consumer<ClaimBean>() {
+                    @Override
+                    public void accept(final ClaimBean claimBean) {
+                        abd.addBean(claimBean);
+                    }
+                });
+    }
+
+    public void observeBeforeBeanDiscovery(@Observes final BeforeBeanDiscovery bbd, final BeanManager beanManager) {
+        bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
+        bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
+        bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
+        bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
+        bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
new file mode 100644
index 0000000..42034b9
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -0,0 +1,49 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+import java.util.function.Function;
+
+@ApplicationScoped
+public class MPJWTProducer {
+
+    @Inject
+    private HttpServletRequest httpServletRequest;
+
+    @Produces
+    @RequestScoped
+    public JsonWebToken currentPrincipal() {
+        Objects.requireNonNull(httpServletRequest, "HTTP Servlet Request is required to produce a JSonWebToken principal.");
+
+        // not very beautiful, but avoids having the MPJWTFilter setting the request or the principal in a thread local
+        // CDI integration already has one - dunno which approach is the best for now
+        final Object tokenAttribute = httpServletRequest.getAttribute(JsonWebToken.class.getName());
+        if (Function.class.isInstance(tokenAttribute)) {
+            return (JsonWebToken) Function.class.cast(tokenAttribute).apply(httpServletRequest);
+        }
+
+        return null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
new file mode 100644
index 0000000..a969515
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
@@ -0,0 +1,67 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.config;
+
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * The public key and expected issuer needed to validate a token.
+ */
+public class JWTAuthContextInfo {
+
+    private RSAPublicKey signerKey;
+    private String issuedBy;
+    private int expGracePeriodSecs = 60;
+
+    public JWTAuthContextInfo() {
+    }
+
+    public JWTAuthContextInfo(final RSAPublicKey signerKey, final String issuedBy) {
+        this.signerKey = signerKey;
+        this.issuedBy = issuedBy;
+    }
+
+    public JWTAuthContextInfo(final JWTAuthContextInfo orig) {
+        this.signerKey = orig.signerKey;
+        this.issuedBy = orig.issuedBy;
+        this.expGracePeriodSecs = orig.expGracePeriodSecs;
+    }
+
+    public RSAPublicKey getSignerKey() {
+        return signerKey;
+    }
+
+    public void setSignerKey(final RSAPublicKey signerKey) {
+        this.signerKey = signerKey;
+    }
+
+    public String getIssuedBy() {
+        return issuedBy;
+    }
+
+    public void setIssuedBy(final String issuedBy) {
+        this.issuedBy = issuedBy;
+    }
+
+    public int getExpGracePeriodSecs() {
+        return expGracePeriodSecs;
+    }
+
+    public void setExpGracePeriodSecs(final int expGracePeriodSecs) {
+        this.expGracePeriodSecs = expGracePeriodSecs;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
new file mode 100644
index 0000000..9247e04
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
@@ -0,0 +1,61 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.config;
+
+import javax.enterprise.context.Dependent;
+import javax.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 JWTAuthContextInfoProvider {
+
+    @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();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
new file mode 100644
index 0000000..34f152f
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
@@ -0,0 +1,36 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.jaxrs;
+
+import org.apache.openejb.observer.Observes;
+import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
+import org.apache.tomee.microprofile.jwt.MPJWTFilter;
+
+/**
+ * OpenEJB/TomEE hack to register a new provider on the fly
+ * Could be package in tomee only or done in another way
+ *
+ * As soon as Roberto is done with the packaging, we can remove all this and providers are going to be scanned automatically
+ */
+public class MPJWPProviderRegistration {
+
+    public void registerProvider(@Observes final ExtensionProviderRegistration event) {
+        event.getProviders().add(new MPJWTFilter.MPJWTExceptionMapper());
+        event.getProviders().add(new MPJWTSecurityAnnotationsInterceptorsFeature());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
new file mode 100644
index 0000000..f604e6b
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
@@ -0,0 +1,57 @@
+package org.apache.tomee.microprofile.jwt.jaxrs;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+public class MPJWTSecurityAnnotationsInterceptor implements ContainerRequestFilter {
+
+    private final javax.ws.rs.container.ResourceInfo resourceInfo;
+    private final ConcurrentMap<Method, Set<String>> rolesAllowed;
+    private final Set<Method> denyAll;
+    private final Set<Method> permitAll;
+
+    public MPJWTSecurityAnnotationsInterceptor(final javax.ws.rs.container.ResourceInfo resourceInfo,
+                                               final ConcurrentMap<Method, Set<String>> rolesAllowed,
+                                               final Set<Method> denyAll,
+                                               final Set<Method> permitAll) {
+        this.resourceInfo = resourceInfo;
+        this.rolesAllowed = rolesAllowed;
+        this.denyAll = denyAll;
+        this.permitAll = permitAll;
+    }
+
+    @Override
+    public void filter(final ContainerRequestContext requestContext) throws IOException {
+        if (permitAll.contains(resourceInfo.getResourceMethod())) {
+            return;
+        }
+
+        if (denyAll.contains(resourceInfo.getResourceMethod())) {
+            forbidden(requestContext);
+            return;
+        }
+
+        final Set<String> roles = rolesAllowed.get(resourceInfo.getResourceMethod());
+        if (roles != null && !roles.isEmpty()) {
+            final SecurityContext securityContext = requestContext.getSecurityContext();
+            for (String role : roles) {
+                if (!securityContext.isUserInRole(role)) {
+                    forbidden(requestContext);
+                    break;
+                }
+            }
+        }
+
+    }
+
+    private void forbidden(final ContainerRequestContext requestContext) {
+        requestContext.abortWith(Response.status(HttpURLConnection.HTTP_FORBIDDEN).build());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
new file mode 100644
index 0000000..58b3203
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
@@ -0,0 +1,144 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.jaxrs;
+
+import javax.annotation.security.DenyAll;
+import javax.annotation.security.PermitAll;
+import javax.annotation.security.RolesAllowed;
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+@Provider
+public class MPJWTSecurityAnnotationsInterceptorsFeature implements DynamicFeature {
+
+    private final ConcurrentMap<Method, Set<String>> rolesAllowed = new ConcurrentHashMap<>();
+    private final Set<Method> denyAll = new HashSet<>();
+    private final Set<Method> permitAll = new HashSet<>();
+
+    @Override
+    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
+
+        final boolean hasSecurity = processSecurityAnnotations(resourceInfo.getResourceClass(), resourceInfo.getResourceMethod());
+
+        if (hasSecurity) { // no need to add interceptor on the resources that don(t have any security requirements to enforce
+            context.register(new MPJWTSecurityAnnotationsInterceptor(resourceInfo, rolesAllowed, denyAll, permitAll));
+        }
+
+    }
+
+    private boolean processSecurityAnnotations(final Class clazz, final Method method) {
+
+        final List<Class<? extends Annotation>[]> classSecurityAnnotations = hasClassLevelAnnotations(clazz,
+                RolesAllowed.class, PermitAll.class, DenyAll.class);
+
+        final List<Class<? extends Annotation>[]> methodSecurityAnnotations = hasMethodLevelAnnotations(method,
+                RolesAllowed.class, PermitAll.class, DenyAll.class);
+
+        if (classSecurityAnnotations.size() == 0 && methodSecurityAnnotations.size() == 0) {
+            return false; // nothing to do
+        }
+
+        /*
+         * Process annotations at the class level
+         */
+        if (classSecurityAnnotations.size() > 1) {
+            throw new IllegalStateException(clazz.getName() + " has more than one security annotation (RolesAllowed, PermitAll, DenyAll).");
+        }
+
+        if (methodSecurityAnnotations.size() > 1) {
+            throw new IllegalStateException(method.toString() + " has more than one security annotation (RolesAllowed, PermitAll, DenyAll).");
+        }
+
+        if (methodSecurityAnnotations.size() == 0) { // no need to deal with class level annotations if the method has some
+            final RolesAllowed classRolesAllowed = (RolesAllowed) clazz.getAnnotation(RolesAllowed.class);
+            final PermitAll classPermitAll = (PermitAll) clazz.getAnnotation(PermitAll.class);
+            final DenyAll classDenyAll = (DenyAll) clazz.getAnnotation(DenyAll.class);
+
+            if (classRolesAllowed != null) {
+                Set<String> roles = new HashSet<String>();
+                final Set<String> previous = rolesAllowed.putIfAbsent(method, roles);
+                if (previous != null) {
+                    roles = previous;
+                }
+                roles.addAll(Arrays.asList(classRolesAllowed.value()));
+            }
+
+            if (classPermitAll != null) {
+                permitAll.add(method);
+            }
+
+            if (classDenyAll != null) {
+                denyAll.add(method);
+            }
+        }
+
+        final RolesAllowed mthdRolesAllowed = method.getAnnotation(RolesAllowed.class);
+        final PermitAll mthdPermitAll = method.getAnnotation(PermitAll.class);
+        final DenyAll mthdDenyAll = method.getAnnotation(DenyAll.class);
+
+        if (mthdRolesAllowed != null) {
+            Set<String> roles = new HashSet<String>();
+            final Set<String> previous = rolesAllowed.putIfAbsent(method, roles);
+            if (previous != null) {
+                roles = previous;
+            }
+            roles.addAll(Arrays.asList(mthdRolesAllowed.value()));
+        }
+
+        if (mthdPermitAll != null) {
+            permitAll.add(method);
+        }
+
+        if (mthdDenyAll != null) {
+            denyAll.add(method);
+        }
+
+        return true;
+    }
+
+    private List<Class<? extends Annotation>[]> hasClassLevelAnnotations(final Class clazz, final Class<? extends Annotation>... annotationsToCheck) {
+        final List<Class<? extends Annotation>[]> list = new ArrayList<>();
+        for (Class<? extends Annotation> annotationToCheck : annotationsToCheck) {
+            if (clazz.isAnnotationPresent(annotationToCheck)) {
+                list.add(annotationsToCheck);
+            }
+        }
+        return list;
+    }
+
+    private List<Class<? extends Annotation>[]> hasMethodLevelAnnotations(final Method method, final Class<? extends Annotation>... annotationsToCheck) {
+        final List<Class<? extends Annotation>[]> list = new ArrayList<>();
+        for (Class<? extends Annotation> annotationToCheck : annotationsToCheck) {
+            if (method.isAnnotationPresent(annotationToCheck)) {
+                list.add(annotationsToCheck);
+            }
+        }
+        return list;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
new file mode 100644
index 0000000..661fbde
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -0,0 +1,360 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.principal;
+
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import javax.security.auth.Subject;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A default implementation of JWTCallerPrincipal using jose4j
+ * Another implementation could use nimbus and another plain JSON-P
+ */
+public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
+
+    private static final Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
+    private final String jwt;
+    private final String type;
+    private final JwtClaims claimsSet;
+
+    /**
+     * Create the DefaultJWTCallerPrincipal from the parsed JWT token and the extracted principal name
+     *
+     * @param jwt  - the parsed JWT token representation
+     * @param name - the extracted unqiue name to use as the principal name; from "upn", "preferred_username" or "sub" claim
+     */
+    public DefaultJWTCallerPrincipal(final String jwt, final String type, final JwtClaims claimsSet, final String name) {
+        super(name);
+        this.jwt = jwt;
+        this.type = type;
+        this.claimsSet = claimsSet;
+        fixJoseTypes();
+    }
+
+    @Override
+    public Set<String> getAudience() {
+        final Set<String> audSet = new HashSet<>();
+        try {
+            final List<String> audList = claimsSet.getStringListClaimValue("aud");
+            if (audList != null) {
+                audSet.addAll(audList);
+            }
+
+        } catch (final MalformedClaimException e) {
+            try {
+                final String aud = claimsSet.getStringClaimValue("aud");
+                audSet.add(aud);
+            } catch (final MalformedClaimException e1) {
+                logger.log(Level.FINEST, "Can't retrieve malformed 'aud' claim.", e);
+            }
+        }
+        return audSet.isEmpty() ? null : audSet;
+    }
+
+    @Override
+    public Set<String> getGroups() {
+        final HashSet<String> groups = new HashSet<>();
+        try {
+            final List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
+            if (globalGroups != null) {
+                groups.addAll(globalGroups);
+            }
+
+        } catch (final MalformedClaimException e) {
+            logger.log(Level.FINEST, "Can't retrieve malformed 'groups' claim.", e);
+        }
+        return groups;
+    }
+
+
+    @Override
+    public Set<String> getClaimNames() {
+        return new HashSet<>(claimsSet.getClaimNames());
+    }
+
+    public String getRawToken() {
+        return jwt;
+    }
+
+    @Override
+    public Object getClaim(final String claimName) {
+        Claims claimType = Claims.UNKNOWN;
+        Object claim = null;
+        try {
+            claimType = Claims.valueOf(claimName);
+        } catch (IllegalArgumentException e) {
+        }
+        // Handle the jose4j NumericDate types and
+        switch (claimType) {
+            case exp:
+            case iat:
+            case auth_time:
+            case nbf:
+            case updated_at:
+                try {
+                    claim = claimsSet.getClaimValue(claimType.name(), Long.class);
+                    if (claim == null) {
+                        claim = new Long(0);
+                    }
+                } catch (final MalformedClaimException e) {
+                    logger.log(Level.FINEST, "Can't retrieve 'updated_at' a malformed claim.", e);
+                }
+                break;
+            case groups:
+                claim = getGroups();
+                break;
+            case aud:
+                claim = getAudience();
+                break;
+            case UNKNOWN:
+                claim = claimsSet.getClaimValue(claimName);
+                break;
+            default:
+                claim = claimsSet.getClaimValue(claimType.name());
+        }
+        return claim;
+    }
+
+    @Override
+    public boolean implies(final Subject subject) {
+        return false;
+    }
+
+    public String toString() {
+        return toString(false);
+    }
+
+    /**
+     * TODO: showAll is ignored and currently assumed true
+     *
+     * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+     *                JsonWebToken interface be displayed.
+     * @return JWTCallerPrincipal string view
+     */
+    @Override
+    public String toString(boolean showAll) {
+        String toString = "DefaultJWTCallerPrincipal{" +
+                "id='" + getTokenID() + '\'' +
+                ", name='" + getName() + '\'' +
+                ", expiration=" + getExpirationTime() +
+                ", notBefore=" + getClaim(Claims.nbf.name()) +
+                ", issuedAt=" + getIssuedAtTime() +
+                ", issuer='" + getIssuer() + '\'' +
+                ", audience=" + getAudience() +
+                ", subject='" + getSubject() + '\'' +
+                ", type='" + type + '\'' +
+                ", issuedFor='" + getClaim("azp") + '\'' +
+                ", authTime=" + getClaim("auth_time") +
+                ", givenName='" + getClaim("given_name") + '\'' +
+                ", familyName='" + getClaim("family_name") + '\'' +
+                ", middleName='" + getClaim("middle_name") + '\'' +
+                ", nickName='" + getClaim("nickname") + '\'' +
+                ", preferredUsername='" + getClaim("preferred_username") + '\'' +
+                ", email='" + getClaim("email") + '\'' +
+                ", emailVerified=" + getClaim(Claims.email_verified.name()) +
+                ", allowedOrigins=" + getClaim("allowedOrigins") +
+                ", updatedAt=" + getClaim("updated_at") +
+                ", acr='" + getClaim("acr") + '\'';
+
+        final StringBuilder tmp = new StringBuilder(toString);
+        tmp.append(", groups=[");
+        for (String group : getGroups()) {
+            tmp.append(group);
+            tmp.append(',');
+        }
+        tmp.setLength(tmp.length() - 1);
+        tmp.append("]}");
+        return tmp.toString();
+    }
+
+    /**
+     * Convert the types jose4j uses for address, sub_jwk, and jwk
+     */
+    private void fixJoseTypes() {
+        if (claimsSet.hasClaim(Claims.address.name())) {
+            replaceMap(Claims.address.name());
+        }
+        if (claimsSet.hasClaim(Claims.jwk.name())) {
+            replaceMap(Claims.jwk.name());
+        }
+        if (claimsSet.hasClaim(Claims.sub_jwk.name())) {
+            replaceMap(Claims.sub_jwk.name());
+        }
+
+        // Handle custom claims
+        final Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
+        for (String name : customClaimNames) {
+            final Object claimValue = claimsSet.getClaimValue(name);
+            if (claimValue instanceof List) {
+                replaceList(name);
+
+            } else if (claimValue instanceof Map) {
+                replaceMap(name);
+
+            } else if (claimValue instanceof Number) {
+                replaceNumber(name);
+            }
+        }
+    }
+
+    /**
+     * Determine the custom claims in the set
+     *
+     * @param claimNames - the current set of claim names in this token
+     * @return the possibly empty set of names for non-Claims claims
+     */
+    private Set<String> filterCustomClaimNames(final Collection<String> claimNames) {
+        final HashSet<String> customNames = new HashSet<>(claimNames);
+        for (Claims claim : Claims.values()) {
+            customNames.remove(claim.name());
+        }
+        return customNames;
+    }
+
+    /**
+     * Replace the jose4j Map<String,Object> with a JsonObject
+     *
+     * @param name - claim name
+     */
+    private void replaceMap(final String name) {
+        try {
+            final Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
+            final JsonObject jsonObject = replaceMap(map);
+            claimsSet.setClaim(name, jsonObject);
+
+        } catch (final MalformedClaimException e) {
+            logger.log(Level.WARNING, "replaceMap failure for: " + name, e);
+        }
+    }
+
+    private JsonObject replaceMap(final Map<String, Object> map) {
+        final JsonObjectBuilder builder = Json.createObjectBuilder();
+
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            final Object entryValue = entry.getValue();
+            if (entryValue instanceof Map) {
+                final JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+                builder.add(entry.getKey(), entryJsonObject);
+
+            } else if (entryValue instanceof List) {
+                final JsonArray array = (JsonArray) wrapValue(entryValue);
+                builder.add(entry.getKey(), array);
+
+            } else if (entryValue instanceof Long || entryValue instanceof Integer) {
+                final long lvalue = ((Number) entryValue).longValue();
+                builder.add(entry.getKey(), lvalue);
+
+            } else if (entryValue instanceof Double || entryValue instanceof Float) {
+                final double value = ((Number) entryValue).doubleValue();
+                builder.add(entry.getKey(), value);
+
+            } else if (entryValue instanceof Boolean) {
+                final boolean flag = ((Boolean) entryValue).booleanValue();
+                builder.add(entry.getKey(), flag);
+
+            } else if (entryValue instanceof String) {
+                builder.add(entry.getKey(), entryValue.toString());
+            }
+        }
+        return builder.build();
+    }
+
+    private JsonValue wrapValue(final Object value) {
+        JsonValue jsonValue = null;
+        if (value instanceof Number) {
+            final Number number = (Number) value;
+            if ((number instanceof Long) || (number instanceof Integer)) {
+                jsonValue = Json.createObjectBuilder()
+                        .add("tmp", number.longValue())
+                        .build()
+                        .getJsonNumber("tmp");
+
+            } else {
+                jsonValue = Json.createObjectBuilder()
+                        .add("tmp", number.doubleValue())
+                        .build()
+                        .getJsonNumber("tmp");
+            }
+
+        } else if (value instanceof Boolean) {
+            final Boolean flag = (Boolean) value;
+            jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+
+        } else if (value instanceof List) {
+            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+            final List list = (List) value;
+            for (Object element : list) {
+                if (element instanceof String) {
+                    arrayBuilder.add(element.toString());
+
+                } else {
+                    JsonValue jvalue = wrapValue(element);
+                    arrayBuilder.add(jvalue);
+                }
+
+            }
+            jsonValue = arrayBuilder.build();
+
+        }
+        return jsonValue;
+    }
+
+
+    /**
+     * Replace the jose4j List<?> with a JsonArray
+     *
+     * @param name - claim name
+     */
+    private void replaceList(final String name) {
+        try {
+            final List list = claimsSet.getClaimValue(name, List.class);
+            final JsonArray array = (JsonArray) wrapValue(list);
+            claimsSet.setClaim(name, array);
+
+        } catch (final MalformedClaimException e) {
+            logger.log(Level.WARNING, "replaceList failure for: " + name, e);
+        }
+    }
+
+    private void replaceNumber(final String name) {
+        try {
+            final Number number = claimsSet.getClaimValue(name, Number.class);
+            final JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
+            claimsSet.setClaim(name, jsonNumber);
+
+        } catch (final MalformedClaimException e) {
+            logger.log(Level.WARNING, "replaceNumber failure for: " + name, e);
+        }
+    }
+
+}
\ No newline at end of file


[5/8] tomee git commit: Make a simple test case to wire up everything and start adding a simple UI on top

Posted by jl...@apache.org.
Make a simple test case to wire up everything and start adding a simple UI on top


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

Branch: refs/heads/fb_tomee8
Commit: b4a44e401a916985caec4b8ea309fe9ab0cbf7c5
Parents: def443a
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Apr 19 23:28:51 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Apr 19 23:28:51 2018 +0200

----------------------------------------------------------------------
 examples/pom.xml                                |   1 +
 examples/rest-mp-jwt/README.md                  |   0
 examples/rest-mp-jwt/pom.xml                    | 278 +++++++++++++++++++
 .../main/java/org/superbiz/moviefun/Movie.java  | 102 +++++++
 .../java/org/superbiz/moviefun/MoviesBean.java  |  91 ++++++
 .../moviefun/rest/ApplicationConfig.java        |  28 ++
 .../org/superbiz/moviefun/rest/LoadRest.java    |  42 +++
 .../rest/MoviesMPJWTConfigurationProvider.java  |  63 +++++
 .../org/superbiz/moviefun/rest/MoviesRest.java  | 113 ++++++++
 .../java/org/superbiz/rest/GreetingService.java |  41 +++
 .../src/main/resources/META-INF/persistence.xml |  31 +++
 examples/rest-mp-jwt/src/main/tomee/tomee.xml   |  27 ++
 .../rest-mp-jwt/src/main/webapp/WEB-INF/web.xml |  46 +++
 .../rest-mp-jwt/src/main/webapp/app/app.less    |  62 +++++
 .../rest-mp-jwt/src/main/webapp/app/config.js   |  45 +++
 .../src/main/webapp/app/js/application.js       | 193 +++++++++++++
 .../rest-mp-jwt/src/main/webapp/app/js/i18n.js  |  66 +++++
 .../rest-mp-jwt/src/main/webapp/app/js/id.js    |  43 +++
 .../rest-mp-jwt/src/main/webapp/app/js/log.js   |  40 +++
 .../src/main/webapp/app/js/model/movie.js       |  48 ++++
 .../src/main/webapp/app/js/model/movies.js      |  35 +++
 .../rest-mp-jwt/src/main/webapp/app/js/start.js |  29 ++
 .../src/main/webapp/app/js/templates.js         |  69 +++++
 ...pplication-table-paginator-button.handlebars |   1 +
 .../templates/application-table-row.handlebars  |   8 +
 .../app/js/templates/application.handlebars     |  50 ++++
 .../app/js/templates/container.handlebars       |  10 +
 .../app/js/templates/load-data-link.handlebars  |   1 +
 .../webapp/app/js/templates/movie.handlebars    |  56 ++++
 .../app/js/view/application-table-paginator.js  |  77 +++++
 .../webapp/app/js/view/application-table-row.js |  63 +++++
 .../src/main/webapp/app/js/view/application.js  | 135 +++++++++
 .../src/main/webapp/app/js/view/container.js    |  62 +++++
 .../src/main/webapp/app/js/view/movie.js        |  75 +++++
 examples/rest-mp-jwt/src/main/webapp/index.jsp  |  36 +++
 .../java/org/superbiz/moviefun/MoviesTest.java  |  88 ++++++
 .../java/org/superbiz/moviefun/TokenUtils.java  | 257 +++++++++++++++++
 .../org/superbiz/rest/GreetingServiceTest.java  |  61 ++++
 .../resources/META-INF/application-client.xml   |   1 +
 .../rest-mp-jwt/src/test/resources/Token1.json  |  20 ++
 .../rest-mp-jwt/src/test/resources/Token2.json  |  12 +
 .../src/test/resources/arquillian.xml           |  32 +++
 .../src/test/resources/privateKey.pem           |  28 ++
 .../src/test/resources/publicKey.pem            |   9 +
 .../microprofile/jwt/cdi/MPJWTCDIExtension.java |  45 +--
 .../jwt/config/JWTAuthContextInfoProvider.java  |  61 ----
 .../jwt/JWTAuthContextInfoProvider.java         |  63 +++++
 .../jwt/AppDeploymentExtension.java             |   3 +-
 48 files changed, 2646 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index fab0d95..18d4971 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -119,6 +119,7 @@ BROKEN, see TOMEE-2140
     <module>rest-applicationcomposer</module>
     <module>rest-cdi</module>
     <module>rest-jaas</module>
+    <module>rest-mp-jwt</module>
     <module>rest-on-ejb</module>
     <module>rest-example</module>
     <module>rest-example-with-application</module>

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/README.md
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/README.md b/examples/rest-mp-jwt/README.md
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/pom.xml b/examples/rest-mp-jwt/pom.xml
new file mode 100644
index 0000000..f2656b3
--- /dev/null
+++ b/examples/rest-mp-jwt/pom.xml
@@ -0,0 +1,278 @@
+<?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>rest-mp-jwt</artifactId>
+  <version>1.1.0-SNAPSHOT</version>
+  <packaging>war</packaging>
+  <name>OpenEJB :: Examples :: REST MP-JWT</name>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <tomee.version>8.0.0-SNAPSHOT</tomee.version>
+    <version.shrinkwrap.resolver>2.0.0</version.shrinkwrap.resolver>
+    <mp-jwt.version>1.1-SNAPSHOT</mp-jwt.version>
+  </properties>
+
+  <build>
+    <defaultGoal>install</defaultGoal>
+
+    <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>
+      <!-- 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.0.3.Final</version>
+        <scope>import</scope>
+        <type>pom</type>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <repositories>
+    <repository>
+      <id>apache-m2-snapshot</id>
+      <name>Apache Snapshot Repository</name>
+      <url>https://repository.apache.org/content/groups/snapshots</url>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tomee</groupId>
+      <artifactId>javaee-api</artifactId>
+      <version>8.0-SNAPSHOT</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.12</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>
+    <dependency>
+      <groupId>org.apache.tomee</groupId>
+      <artifactId>ziplock</artifactId>
+      <version>${tomee.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>backbonejs</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>bootstrap</artifactId>
+      <version>3.1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>handlebars</artifactId>
+      <version>1.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>jquery</artifactId>
+      <version>2.1.0-1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>json2</artifactId>
+      <version>20110223</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>less</artifactId>
+      <version>1.6.0-1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>requirejs</artifactId>
+      <version>2.1.10</version>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>requirejs-text</artifactId>
+      <version>2.0.10</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>arquillian-tomee-embedded</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.tomee</groupId>
+          <artifactId>arquillian-tomee-embedded</artifactId>
+          <version>${tomee.version}</version>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.tomee</groupId>
+          <artifactId>tomee-embedded</artifactId>
+          <version>${tomee.version}</version>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.tomee</groupId>
+          <artifactId>mp-jwt</artifactId>
+          <version>${tomee.version}</version>
+          <scope>provided</scope>
+        </dependency>
+      </dependencies>
+    </profile>
+    <profile>
+      <id>arquillian-tomee-remote</id>
+      <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>
+      </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/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/Movie.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/Movie.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/Movie.java
new file mode 100644
index 0000000..4e067bb
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/Movie.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.moviefun;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@XmlRootElement(name = "movie")
+public class Movie {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private long id;
+
+    private String director;
+    private String title;
+    private int year;
+    private String genre;
+    private int rating;
+
+    public Movie() {
+    }
+
+    public Movie(String title, String director, String genre, int rating, int year) {
+        this.director = director;
+        this.title = title;
+        this.year = year;
+        this.genre = genre;
+        this.rating = rating;
+    }
+
+    public Movie(String director, String title, int year) {
+        this.director = director;
+        this.title = title;
+        this.year = year;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long 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;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(int year) {
+        this.year = year;
+    }
+
+    public String getGenre() {
+        return genre;
+    }
+
+    public void setGenre(String genre) {
+        this.genre = genre;
+    }
+
+    public int getRating() {
+        return rating;
+    }
+
+    public void setRating(int rating) {
+        this.rating = rating;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java
new file mode 100644
index 0000000..2580c9f
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/MoviesBean.java
@@ -0,0 +1,91 @@
+/**
+ * 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;
+
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.metamodel.EntityType;
+import java.util.List;
+
+@Stateless
+public class MoviesBean {
+
+    @PersistenceContext(unitName = "movie-unit")
+    private EntityManager entityManager;
+
+    public Movie find(Long id) {
+        return entityManager.find(Movie.class, id);
+    }
+
+    public void addMovie(Movie movie) {
+        entityManager.persist(movie);
+    }
+
+    public void editMovie(Movie movie) {
+        entityManager.merge(movie);
+    }
+
+    public void deleteMovie(long id) {
+        Movie movie = entityManager.find(Movie.class, id);
+        entityManager.remove(movie);
+    }
+
+    public List<Movie> getMovies(Integer firstResult, Integer maxResults, String field, String searchTerm) {
+        CriteriaBuilder qb = entityManager.getCriteriaBuilder();
+        CriteriaQuery<Movie> cq = qb.createQuery(Movie.class);
+        Root<Movie> root = cq.from(Movie.class);
+        EntityType<Movie> type = entityManager.getMetamodel().entity(Movie.class);
+        if (field != null && searchTerm != null && !"".equals(field.trim()) && !"".equals(searchTerm.trim())) {
+            Path<String> path = root.get(type.getDeclaredSingularAttribute(field.trim(), String.class));
+            Predicate condition = qb.like(path, "%" + searchTerm.trim() + "%");
+            cq.where(condition);
+        }
+        TypedQuery<Movie> q = entityManager.createQuery(cq);
+        if (maxResults != null) {
+            q.setMaxResults(maxResults);
+        }
+        if (firstResult != null) {
+            q.setFirstResult(firstResult);
+        }
+        return q.getResultList();
+    }
+
+    public int count(String field, String searchTerm) {
+        CriteriaBuilder qb = entityManager.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = qb.createQuery(Long.class);
+        Root<Movie> root = cq.from(Movie.class);
+        EntityType<Movie> type = entityManager.getMetamodel().entity(Movie.class);
+        cq.select(qb.count(root));
+        if (field != null && searchTerm != null && !"".equals(field.trim()) && !"".equals(searchTerm.trim())) {
+            Path<String> path = root.get(type.getDeclaredSingularAttribute(field.trim(), String.class));
+            Predicate condition = qb.like(path, "%" + searchTerm.trim() + "%");
+            cq.where(condition);
+        }
+        return entityManager.createQuery(cq).getSingleResult().intValue();
+    }
+
+    public void clean() {
+        entityManager.createQuery("delete from Movie").executeUpdate();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java
new file mode 100644
index 0000000..5a7bd4d
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/ApplicationConfig.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <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 javax.ws.rs.ApplicationPath;
+import javax.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

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/LoadRest.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/LoadRest.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/LoadRest.java
new file mode 100644
index 0000000..6969221
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/LoadRest.java
@@ -0,0 +1,42 @@
+/**
+ * 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.superbiz.moviefun.Movie;
+import org.superbiz.moviefun.MoviesBean;
+
+import javax.ejb.EJB;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+@Path("load")
+public class LoadRest {
+    @EJB
+    private MoviesBean moviesBean;
+
+    @POST
+    public void load() {
+        moviesBean.addMovie(new Movie("Wedding Crashers", "David Dobkin", "Comedy", 7, 2005));
+        moviesBean.addMovie(new Movie("Starsky & Hutch", "Todd Phillips", "Action", 6, 2004));
+        moviesBean.addMovie(new Movie("Shanghai Knights", "David Dobkin", "Action", 6, 2003));
+        moviesBean.addMovie(new Movie("I-Spy", "Betty Thomas", "Adventure", 5, 2002));
+        moviesBean.addMovie(new Movie("The Royal Tenenbaums", "Wes Anderson", "Comedy", 8, 2001));
+        moviesBean.addMovie(new Movie("Zoolander", "Ben Stiller", "Comedy", 6, 2001));
+        moviesBean.addMovie(new Movie("Shanghai Noon", "Tom Dey", "Comedy", 7, 2000));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java
new file mode 100644
index 0000000..3bea531
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesMPJWTConfigurationProvider.java
@@ -0,0 +1,63 @@
+/*
+ *     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.JWTAuthContextInfo;
+
+import javax.enterprise.context.Dependent;
+import javax.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();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java
new file mode 100644
index 0000000..7020864
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/moviefun/rest/MoviesRest.java
@@ -0,0 +1,113 @@
+/**
+ * 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.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+import org.superbiz.moviefun.Movie;
+import org.superbiz.moviefun.MoviesBean;
+
+import javax.annotation.security.RolesAllowed;
+import javax.ejb.EJB;
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
+import java.util.List;
+
+@Path("movies")
+@Produces({"application/json"})
+public class MoviesRest {
+
+    @EJB
+    private MoviesBean service;
+
+    @Inject
+    @Claim("raw_token")
+    private ClaimValue<String> rawToken;
+
+    @Inject
+    @Claim("iss")
+    private ClaimValue<String> issuer;
+
+    @Inject
+    @Claim("jti")
+    private ClaimValue<String> jti;
+
+    @Inject
+    private JsonWebToken jwtPrincipal;
+
+    @Context
+    private SecurityContext securityContext;
+
+    @GET
+    @Path("{id}")
+    public Movie find(@PathParam("id") Long id) {
+        return service.find(id);
+    }
+
+    @GET
+    public List<Movie> getMovies(@QueryParam("first") Integer first, @QueryParam("max") Integer max,
+                                 @QueryParam("field") String field, @QueryParam("searchTerm") String searchTerm) {
+        return service.getMovies(first, max, field, searchTerm);
+    }
+
+    @POST
+    @Consumes("application/json")
+    @RolesAllowed("create")
+    public Movie addMovie(Movie movie) {
+        service.addMovie(movie);
+        return movie;
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes("application/json")
+    @RolesAllowed("update")
+    public Movie editMovie(
+            @PathParam("id") final long id,
+            Movie movie
+    ) {
+        service.editMovie(movie);
+        return movie;
+    }
+
+    @DELETE
+    @Path("{id}")
+    @RolesAllowed("delete")
+    public void deleteMovie(@PathParam("id") long id) {
+        service.deleteMovie(id);
+    }
+
+    @GET
+    @Path("count")
+    @Produces(MediaType.TEXT_PLAIN)
+    public int count(@QueryParam("field") String field, @QueryParam("searchTerm") String searchTerm) {
+        return service.count(field, searchTerm);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/java/org/superbiz/rest/GreetingService.java
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/java/org/superbiz/rest/GreetingService.java b/examples/rest-mp-jwt/src/main/java/org/superbiz/rest/GreetingService.java
new file mode 100644
index 0000000..eb4434e
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/java/org/superbiz/rest/GreetingService.java
@@ -0,0 +1,41 @@
+/**
+ * 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.rest;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.Locale;
+
+@Path("/greeting")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class GreetingService {
+
+    @GET
+    public String message() {
+        return "Hi Microprofile JWT!";
+    }
+
+    @POST
+    public String lowerCase(final String message) {
+        return message.toLowerCase(Locale.ENGLISH);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/resources/META-INF/persistence.xml b/examples/rest-mp-jwt/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..ec38aaa
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+  <persistence-unit name="movie-unit">
+    <jta-data-source>movieDatabase</jta-data-source>
+    <non-jta-data-source>movieDatabaseUnmanaged</non-jta-data-source>
+    <class>org.superbiz.moviefun.Movie</class>
+
+    <properties>
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+    </properties>
+  </persistence-unit>
+</persistence>

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/tomee/tomee.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/tomee/tomee.xml b/examples/rest-mp-jwt/src/main/tomee/tomee.xml
new file mode 100644
index 0000000..f25d5f8
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/tomee/tomee.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<tomee>
+  <Resource id="HSQLDB Database" type="DataSource">
+    JdbcDriver org.hsqldb.jdbcDriver
+    JdbcUrl jdbc:hsqldb:file:target/db/moviefun
+    UserName sa
+    Password
+  </Resource>
+</tomee>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml b/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..328247d
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+
+<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+  <welcome-file-list>
+    <welcome-file>index.jsp</welcome-file>
+  </welcome-file-list>
+
+  <!-- The trick is to put all your static files under the same directory and map the "default" servlet to it -->
+  <servlet-mapping>
+    <servlet-name>default</servlet-name>
+    <url-pattern>/app/*</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>default</servlet-name>
+    <url-pattern>/webjars/*</url-pattern>
+  </servlet-mapping>
+
+  <!-- Any other request will point to the "index.jsp" page. This way Backbone knows how to manage page transitions
+   at the client side in case the user starts the application from a permalink. -->
+  <servlet>
+    <servlet-name>application</servlet-name>
+    <jsp-file>/index.jsp</jsp-file>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>application</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+</web-app>
+

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/app.less
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/app.less b/examples/rest-mp-jwt/src/main/webapp/app/app.less
new file mode 100644
index 0000000..61fd5e2
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/app.less
@@ -0,0 +1,62 @@
+/*!
+ * 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.
+ */
+
+body {
+  @content-margin-top: 80px;
+
+  .ux-movie-window {
+    .modal-dialog {
+      padding-top: 90px;
+      padding-bottom: 0px;
+    }
+  }
+
+  .ux-landing {
+    margin-top: @content-margin-top;
+  }
+
+  .ux-setup {
+    margin-top: @content-margin-top;
+  }
+
+  .ux-application {
+    margin-top: @content-margin-top;
+
+    .pagination {
+      margin-top: 0px;
+      margin-bottom: 0px;
+    }
+
+    th:last-child {
+      width: 5px;
+    }
+
+    .ux-add-btn {
+      position: absolute;
+      bottom: 20px;
+      right: 30px;
+    }
+
+    a.ux-delete-row:hover, a.ux-edit-row:hover {
+      cursor: hand;
+    }
+
+    .panel-body>.input-group {
+      margin-bottom: 15px;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/config.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/config.js b/examples/rest-mp-jwt/src/main/webapp/app/config.js
new file mode 100644
index 0000000..bbdc5e1
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/config.js
@@ -0,0 +1,45 @@
+/**
+ *
+ * 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.
+ */
+
+var APP_CONFIG = {
+    baseUrl: window.ux.ROOT_URL,
+    paths: {
+        'text': 'webjars/requirejs-text/2.0.10/text',
+        'lib/less': 'webjars/less/1.6.0/less.min',
+        'lib/jquery': 'webjars/jquery/2.1.0/jquery.min',
+        'lib/bootstrap': 'webjars/bootstrap/3.1.0/js/bootstrap.min',
+        'lib/handlebars': 'webjars/handlebars/1.2.1/handlebars.min',
+        'lib/underscore': 'webjars/underscorejs/1.4.3/underscore-min',
+        'lib/json2': 'webjars/json2/20110223/json2.min',
+        'lib/backbone': 'webjars/backbonejs/1.0.0/backbone'
+    },
+    shim: {
+        'lib/bootstrap': {
+            deps: ['lib/jquery']
+        },
+        'lib/underscore': {
+            exports: '_'
+        },
+        'lib/backbone': {
+            deps: ['lib/jquery', 'lib/json2', 'lib/underscore']
+        },
+        'app/js/templates': {
+            deps: ['lib/underscore', 'app/js/i18n']
+        }
+    }
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/application.js b/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
new file mode 100644
index 0000000..9ec4cab
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
@@ -0,0 +1,193 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = [
+        'app/js/view/container',
+        'app/js/view/application',
+        'app/js/view/application-table-paginator',
+        'app/js/view/movie',
+        'lib/underscore',
+        'app/js/model/movies',
+        'app/js/model/movie',
+        'app/js/i18n',
+        'lib/less', 'lib/backbone', 'lib/jquery', 'lib/bootstrap'
+    ];
+    define(deps, function (containerView, applicationView, paginator, MovieView, underscore, moviesList, MovieModel) {
+        var max = 5;
+        var appState = {
+            page: null,
+            fieldName: null,
+            fieldValue: null
+        };
+        containerView.render();
+
+        $.ajaxSetup({ cache: false });
+
+        function loadPage(pageNumber, fieldName, fieldValue) {
+            var data = {
+                max: max,
+                first: ((pageNumber - 1) * max)
+            };
+            if (fieldName && fieldValue) {
+                data.field = fieldName;
+                data.searchTerm = fieldValue;
+            }
+            applicationView.setFilter(fieldName, fieldValue);
+            moviesList.fetch({
+                data: data,
+                success: function (result) {
+                    applicationView.addRows(result.models);
+
+                    $.ajax({
+                        url: window.ux.ROOT_URL + 'rest/movies/count/',
+                        method: 'GET',
+                        dataType: 'json',
+                        data: {
+                            field: appState.fieldName,
+                            searchTerm: appState.fieldValue
+                        },
+                        success: function (total) {
+                            var count = Math.ceil(total / max);
+                            paginator.setCount(count);
+                            applicationView.setPaginator(count);
+                        }
+                    });
+                }
+            });
+        }
+
+        function start() {
+            //Starting the backbone router.
+            var Router = Backbone.Router.extend({
+                routes: {
+                    '': 'showApplication',
+                    'application': 'showApplication',
+                    'application/:page': 'showApplication',
+                    'application/:page/:field/:value': 'showApplication'
+                },
+
+                showApplication: function (page, fieldName, fieldValue) {
+                    var me = this;
+                    appState.page = page;
+                    appState.fieldName = fieldName;
+                    appState.fieldValue = fieldValue;
+                    containerView.showView(applicationView);
+                    if (!page || !underscore.isNumber(Number(page))) {
+                        me.showApplication(1);
+                    } else {
+                        loadPage(Number(page), fieldName, fieldValue);
+                        if (fieldName) {
+                            me.navigate('application/' + page + '/' + fieldName + '/' + fieldValue, {
+                                trigger: false
+                            });
+                        } else {
+                            me.navigate('application/' + page, {
+                                trigger: false
+                            });
+                        }
+                    }
+                }
+            });
+            var router = new Router();
+
+            applicationView.on('load-sample', function () {
+                $.ajax({
+                    url: window.ux.ROOT_URL + 'rest/load/',
+                    method: 'POST',
+                    dataType: 'json',
+                    data: {},
+                    success: function (data) {
+                        router.showApplication();
+                    }
+                });
+            });
+
+            applicationView.on('delete', function (data) {
+                data.model.destroy({
+                    success: function () {
+                        router.showApplication(appState.page, appState.fieldName, appState.fieldValue);
+                    }
+                });
+            });
+
+            function showMovieWindow(model) {
+                var view = new MovieView({
+                    model: model
+                });
+                view.render();
+                view.on('save-model', function (data) {
+                    data.model.save({}, {
+                        success: function () {
+                            view.remove();
+                            loadPage(appState.page, appState.fieldName, appState.fieldValue);
+                        }
+                    });
+                });
+                $('body').append(view.$el);
+                view.$el.modal({});
+            }
+
+            applicationView.on('add', function () {
+                showMovieWindow(new MovieModel({}));
+            });
+
+            applicationView.on('edit', function (data) {
+                showMovieWindow(data.model);
+            });
+
+            applicationView.on('filter', function (data) {
+                router.navigate('application/1/' + data.filterType + '/' + data.filterValue, {
+                    trigger: true
+                });
+            });
+
+            applicationView.on('clear-filter', function (data) {
+                router.navigate('application/1', {
+                    trigger: true
+                });
+            });
+
+            paginator.on('go-to-page', function (data) {
+                var page = data.number;
+                if (page === 'last') {
+                    page = paginator.getCount();
+                }
+                router.showApplication(page, appState.fieldName, appState.fieldValue);
+            });
+
+            //Starting the backbone history.
+            Backbone.history.start({
+                pushState: true,
+                root: window.ux.ROOT_URL // This value is set by <c:url>
+            });
+
+            return {
+                getRouter: function () {
+                    return router;
+                }
+            };
+        }
+
+        return {
+            start: start
+        };
+    });
+}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js b/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
new file mode 100644
index 0000000..2603dec
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
@@ -0,0 +1,66 @@
+/**
+ *
+ * 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.
+ "use strict";
+ */
+
+define(['lib/underscore', 'lib/handlebars', 'app/js/log'], function (underscore) {
+    'use strict';
+
+    var missing = Handlebars.compile('[!{{key}}!]');
+    var messages = {
+        'application.name': 'Moviefun',
+        'load.dada': 'Click here to load sample data',
+        'movies': 'Movies',
+        'title': 'Title',
+        'director': 'Director',
+        'genre': 'Genre',
+        'rating': 'Rating',
+        'year': 'Year',
+        'add.movie': 'Add movie',
+        'movie': 'Movie',
+        'close': 'Close',
+        'save': 'Save',
+
+        'dummy': ''
+    };
+
+    underscore.each(underscore.keys(messages), function (key) {
+        var template = Handlebars.compile(messages[key]);
+        messages[key] = template;
+    });
+
+    var get = function (key, values) {
+        var template = messages[key];
+        var cfg = values;
+        if (!template) {
+            template = missing;
+            cfg = {
+                key: key
+            };
+            window.console.error('Missing i18n message.', key);
+        }
+        return template(cfg);
+    };
+
+    Handlebars.registerHelper('i18n', function (key) {
+        return get(key);
+    });
+
+    return {
+        get: get
+    };
+});

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/id.js b/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
new file mode 100644
index 0000000..fc4c56a
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
@@ -0,0 +1,43 @@
+/**
+ *
+ * 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.
+ "use strict";
+ */
+
+define(['lib/underscore', 'lib/handlebars'], function (underscore) {
+    'use strict';
+
+    var value = underscore.uniqueId('moviefun_');
+
+    var current = function () {
+        return value;
+    };
+    var next = function () {
+        value = underscore.uniqueId('moviefun_');
+        return value;
+    };
+    Handlebars.registerHelper('id_current', function (key) {
+        return current();
+    });
+    Handlebars.registerHelper('id_next', function (key) {
+        return next();
+    });
+
+    return {
+        current: current,
+        next: next
+    };
+});

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/log.js b/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
new file mode 100644
index 0000000..6e79b98
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
@@ -0,0 +1,40 @@
+/**
+ *
+ * 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.
+ */
+
+define([], function () {
+    'use strict';
+
+    var noOp = function () {
+        return ''; // no-op
+    };
+
+    if (!window.console) {
+        window.console = {};
+    }
+
+    function createIfNull(functionName) {
+        if (!window.console[functionName]) {
+            window.console[functionName] = noOp;
+        }
+    }
+
+    createIfNull('error');
+    createIfNull('warn');
+    createIfNull('log');
+    createIfNull('info');
+});

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
new file mode 100644
index 0000000..36be222
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
@@ -0,0 +1,48 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['lib/backbone'];
+    define(deps, function () {
+        var isString = function (obj) {
+            return Object.prototype.toString.call(obj) === '[object String]';
+        };
+        return Backbone.Model.extend({
+            urlRoot: window.ux.ROOT_URL + 'rest/movies',
+            idAttribute: 'id',
+            toJSON: function () {
+                if (!!this.attributes.rating && isString(this.attributes.rating)) {
+                    this.attributes.rating = parseInt(this.attributes.rating, 10);
+                }
+                if (!!this.attributes.year && isString(this.attributes.year)) {
+                    this.attributes.year = parseInt(this.attributes.year, 10);
+                }
+                if (!!this.attributes.id && isString(this.attributes.id)) {
+                    this.attributes.id = parseInt(this.attributes.id, 10);
+                }
+                return this.attributes;
+            },
+            defaults: {
+                rating: 5,
+                year: new Date().getFullYear()
+            }
+        });
+    });
+}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
new file mode 100644
index 0000000..828d2f8
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
@@ -0,0 +1,35 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/model/movie', 'lib/backbone'];
+    define(deps, function (Movie) {
+        var Cls = Backbone.Collection.extend({
+            model: Movie,
+            url: window.ux.ROOT_URL + 'rest/movies',
+            parse: function (response) {
+                return response;
+            }
+        });
+        return new Cls();
+    });
+}());
+
+

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/start.js b/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
new file mode 100644
index 0000000..33f7fbd
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
@@ -0,0 +1,29 @@
+/**
+ *
+ * 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.
+ */
+
+require.config(APP_CONFIG);
+
+requirejs(['app/js/application'], function (app) {
+    'use strict';
+
+    $(window.document).ready(function () {
+        // all the action is in app
+        app.start();
+    });
+});
+

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js b/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
new file mode 100644
index 0000000..e3f3300
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
@@ -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
+ *
+ *     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.
+ */
+
+(function () {
+    'use strict';
+
+    var files = [
+        'container',
+        'application',
+        'application-table-row',
+        'application-table-paginator-button',
+        'load-data-link',
+        'movie'
+    ];
+
+    function loop(values, callback) {
+        var index;
+        for (index = 0; index < values.length; index += 1) {
+            callback(values[index], index);
+        }
+    }
+
+    // Preparing the "requirements" paths.
+    var requirements = [];
+    loop(files, function (file) {
+        requirements.push('text!app/js/templates/' + file + '.handlebars');
+    });
+
+    define(requirements, function () {
+        var templates = {};
+
+        var myArgs = arguments;
+        loop(files, function (file, i) {
+            templates[file] = Handlebars.compile(myArgs[i]);
+        });
+
+        return {
+            getValue: function (templateName, cfg) {
+                var template = templates[templateName];
+                if (!template) {
+                    throw 'Template not registered. "' + templateName + '"';
+                }
+                var result;
+                if (cfg) {
+                    result = template(cfg);
+                } else {
+                    result = template({});
+                }
+                return result;
+            }
+        };
+    });
+}());
+

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
new file mode 100644
index 0000000..0031aba
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
@@ -0,0 +1 @@
+<li><a href="{{pageNumber}}">{{pageText}}</a></li>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
new file mode 100644
index 0000000..dc9bf7c
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
@@ -0,0 +1,8 @@
+<td><a href="edit" class="ux-edit-row">{{title}}</a></td>
+<td>{{director}}</td>
+<td>{{genre}}</td>
+<td>{{rating}}</td>
+<td>{{year}}</td>
+<td>
+    <a href="delete" class="ux-delete-row"><span class="glyphicon glyphicon-trash"></span></a>
+</td>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
new file mode 100644
index 0000000..f15d1a9
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
@@ -0,0 +1,50 @@
+<div class="row">
+    <div class="col-md-12">
+        <div class="panel panel-default">
+            <div class="panel-heading">
+                <h3 class="panel-title">{{i18n "movies"}}</h3>
+            </div>
+            <div class="panel-body">
+                <div class="input-group">
+                    <div class="input-group-btn">
+                        <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+                            <span class="ux-selected-filter">{{i18n "title"}}</span> <span class="caret"></span>
+                        </button>
+                        <ul class="dropdown-menu" role="menu">
+                            <li><a href="title" class="ux-filter">{{i18n "title"}}</a></li>
+                            <li><a href="director" class="ux-filter">{{i18n "director"}}</a></li>
+                            <li><a href="genre" class="ux-filter">{{i18n "genre"}}</a></li>
+                            <li><a href="rating" class="ux-filter">{{i18n "rating"}}</a></li>
+                            <li><a href="year" class="ux-filter">{{i18n "year"}}</a></li>
+                        </ul>
+                    </div><!-- /btn-group -->
+                    <input type="text" class="form-control ux-filter-field">
+                    <span class="input-group-btn">
+                        <button class="btn btn-primary ux-clear-filter-action" type="button">
+                            <span class="glyphicon glyphicon-remove-circle"></span>
+                        </button>
+                        <button class="btn btn-primary ux-filter-action" type="button">
+                            <span class="glyphicon glyphicon-search"></span>
+                        </button>
+                    </span>
+                </div>
+                <table class="table table-bordered table-striped table-hover">
+                    <thead>
+                    <tr>
+                        <th>{{i18n "title"}}</th>
+                        <th>{{i18n "director"}}</th>
+                        <th>{{i18n "genre"}}</th>
+                        <th>{{i18n "rating"}}</th>
+                        <th>{{i18n "year"}}</th>
+                        <th></th>
+                    </tr>
+                    </thead>
+                    <tbody></tbody>
+                </table>
+                <button type="button" class="btn btn-primary ux-add-btn">{{i18n "add.movie"}}</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
new file mode 100644
index 0000000..dba60dd
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
@@ -0,0 +1,10 @@
+<div class="navbar navbar-inverse navbar-fixed-top">
+    <div class="container">
+        <div class="navbar-header">
+            <a class="navbar-brand" href="#">{{i18n "application.name"}}</a>
+        </div>
+    </div>
+</div>
+<div class="container">
+    <div class="ux-contentarea"></div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
new file mode 100644
index 0000000..1785578
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
@@ -0,0 +1 @@
+<a href="load-data">{{i18n "load.dada"}}</a>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
new file mode 100644
index 0000000..97c511c
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
@@ -0,0 +1,56 @@
+<div class="modal-dialog">
+    <div class="modal-content">
+        <div class="modal-header">
+            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+            <h4 class="modal-title">{{i18n "movie"}}</h4>
+        </div>
+        <div class="modal-body">
+            <form class="form-horizontal" role="form">
+                <div class="form-group">
+                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "title"}}</label>
+
+                    <div class="col-lg-10">
+                        <input class="form-control ux-title" id="{{id_current}}" placeholder="{{i18n 'title'}}"
+                               type="text" value="{{title}}">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "director"}}</label>
+
+                    <div class="col-lg-10">
+                        <input class="form-control ux-director" id="{{id_current}}"
+                               type="text" placeholder="{{i18n 'director'}}" value="{{director}}">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "genre"}}</label>
+
+                    <div class="col-lg-10">
+                        <input class="form-control ux-genre" id="{{id_current}}" placeholder="{{i18n 'genre'}}"
+                               type="text" value="{{genre}}">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "rating"}}</label>
+
+                    <div class="col-lg-10">
+                        <input class="form-control ux-rating" id="{{id_current}}"
+                               type="number" min="0" max="10" placeholder="{{i18n 'rating'}}" value="{{rating}}">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "year"}}</label>
+
+                    <div class="col-lg-10">
+                        <input class="form-control ux-year" id="{{id_current}}" placeholder="{{i18n 'year'}}"
+                               type="number" min="1900" max="{{currentYear}}" value="{{year}}">
+                    </div>
+                </div>
+            </form>
+        </div>
+        <div class="modal-footer">
+            <button type="button" class="btn btn-default ux-close" data-dismiss="modal">{{i18n "close"}}</button>
+            <button type="button" class="btn btn-primary ux-save" data-dismiss="modal">{{i18n "save"}}</button>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
new file mode 100644
index 0000000..c5d2422
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
@@ -0,0 +1,77 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/templates', 'lib/backbone'];
+    define(deps, function (templates) {
+
+        var View = Backbone.View.extend({
+            tagName: 'ul',
+            className: 'pagination',
+
+            count: 0,
+
+            events: {
+                'click a': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    var myLink = $(evt.target);
+                    var href = myLink.attr('href');
+                    me.trigger('go-to-page', {
+                        number: href
+                    });
+                }
+            },
+
+            render: function () {
+                var me = this;
+                me.$el.empty();
+                me.$el.append(templates.getValue('application-table-paginator-button', {
+                    pageNumber: '1',
+                    pageText: '<<'
+                }));
+                var i;
+                for (i = 1; i < me.count + 1; i += 1) {
+                    me.$el.append(templates.getValue('application-table-paginator-button', {
+                        pageNumber: i,
+                        pageText: i
+                    }));
+                }
+                me.$el.append(templates.getValue('application-table-paginator-button', {
+                    pageNumber: 'last',
+                    pageText: '>>'
+                }));
+                return this;
+            },
+
+            setCount: function (count) {
+                var me = this;
+                me.count = count;
+                me.render();
+            },
+
+            getCount: function () {
+                var me = this;
+                return me.count;
+            }
+        });
+        return new View().render();
+    });
+}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
new file mode 100644
index 0000000..771a062
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
@@ -0,0 +1,63 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/templates', 'lib/backbone'];
+    define(deps, function (templates) {
+
+        var View = Backbone.View.extend({
+            tagName: 'tr',
+            events: {
+                'click .ux-delete-row': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('delete', {
+                        model: me.model
+                    });
+                    me.remove();
+                },
+                'click .ux-edit-row': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('edit', {
+                        model: me.model
+                    });
+                }
+            },
+
+            render: function () {
+                var me = this;
+                if (!this.options.isRendered) {
+                    me.$el.empty();
+                    me.$el.append(templates.getValue('application-table-row', {
+                        title: me.model.get('title'),
+                        director: me.model.get('director'),
+                        genre: me.model.get('genre'),
+                        rating: me.model.get('rating'),
+                        year: me.model.get('year')
+                    }));
+                    me.options.isRendered = true;
+                }
+                return this;
+            }
+        });
+        return View;
+    });
+}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/b4a44e40/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
new file mode 100644
index 0000000..7dae6b3
--- /dev/null
+++ b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
@@ -0,0 +1,135 @@
+/**
+ *
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    var deps = ['app/js/templates', 'app/js/view/application-table-row', 'app/js/view/application-table-paginator',
+        'lib/underscore', 'app/js/i18n', 'lib/backbone'];
+    define(deps, function (templates, TableRowView, paginator, underscore, i18n) {
+
+        var View = Backbone.View.extend({
+            tagName: 'div',
+            className: 'ux-application',
+
+            loadDataLink: $(templates.getValue('load-data-link', {})),
+
+            filterOption: 'title',
+
+            events: {
+                'click .ux-filter': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    var selected = $(me.$el.find('.ux-selected-filter').get(0));
+                    var myLink = $(evt.target);
+                    me.filterOption = myLink.attr('href');
+                    selected.html(i18n.get(me.filterOption, {}));
+                },
+                'click .ux-filter-action': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    var filterValue = $(me.$el.find('.ux-filter-field').get(0)).val();
+                    filterValue = $.trim(filterValue);
+                    if (filterValue !== '') {
+                        me.trigger('filter', {
+                            filterType: me.filterOption,
+                            filterValue: filterValue
+                        });
+                    }
+                },
+                'click .ux-clear-filter-action': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('clear-filter', {});
+                },
+                'click .ux-application': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('navigate', {
+                        path: 'application'
+                    });
+                },
+                'click .ux-add-btn': function (evt) {
+                    evt.preventDefault();
+                    var me = this;
+                    me.trigger('add', {});
+                }
+            },
+
+            setFilter: function (fieldName, fieldValue) {
+                var field = fieldName;
+                var value = fieldValue;
+                if (!fieldName || $.trim(fieldName) === '') {
+                    field = 'title';
+                    value = '';
+                }
+                var me = this;
+                me.filterOption = field;
+                $(me.$el.find('.ux-selected-filter').get(0)).html(i18n.get(me.filterOption, {}));
+                $(me.$el.find('.ux-filter-field').get(0)).val(value);
+            },
+
+            render: function () {
+                var me = this;
+                if (!this.options.isRendered) {
+                    me.$el.empty();
+                    me.$el.append(templates.getValue('application', {}));
+                    me.loadDataLink.on('click', function (evt) {
+                        evt.preventDefault();
+                        me.trigger('load-sample', {});
+                    });
+                    me.options.isRendered = true;
+                }
+                return this;
+            },
+
+            addRows: function (rows) {
+                var me = this;
+                var tbody = $(me.$el.find('tbody').get(0));
+                tbody.empty();
+                paginator.$el.detach();
+                me.loadDataLink.detach();
+                underscore.each(rows, function (model) {
+                    var row = new TableRowView({
+                        model: model
+                    });
+                    row.on('delete', function (data) {
+                        me.trigger('delete', data);
+                    });
+                    row.on('edit', function (data) {
+                        me.trigger('edit', data);
+                    });
+                    tbody.append(row.render().$el);
+                });
+            },
+
+            setPaginator: function (count) {
+                var me = this;
+                paginator.$el.detach();
+                me.loadDataLink.detach();
+                var table = $(me.$el.find('.table').get(0));
+                if (count) {
+                    table.after(paginator.$el);
+                } else {
+                    table.after(me.loadDataLink);
+                }
+            }
+        });
+        return new View();
+    });
+}());


[6/8] tomee git commit: POM clean up and use final MP_JWT 1.0 until the next release is out

Posted by jl...@apache.org.
POM clean up and use final MP_JWT 1.0 until the next release is out


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

Branch: refs/heads/fb_tomee8
Commit: ebf29ec904d4fdf6e8efb385da86d940474b5dd7
Parents: b4a44e4
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Apr 20 12:52:32 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Apr 20 12:52:32 2018 +0200

----------------------------------------------------------------------
 examples/rest-mp-jwt/pom.xml     | 3 ++-
 mp-jwt/pom.xml                   | 4 ----
 pom.xml                          | 3 +++
 tck/microprofile-tck/jwt/pom.xml | 9 ++-------
 4 files changed, 7 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/ebf29ec9/examples/rest-mp-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/pom.xml b/examples/rest-mp-jwt/pom.xml
index f2656b3..f100601 100644
--- a/examples/rest-mp-jwt/pom.xml
+++ b/examples/rest-mp-jwt/pom.xml
@@ -30,11 +30,12 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <tomee.version>8.0.0-SNAPSHOT</tomee.version>
     <version.shrinkwrap.resolver>2.0.0</version.shrinkwrap.resolver>
-    <mp-jwt.version>1.1-SNAPSHOT</mp-jwt.version>
+    <mp-jwt.version>1.0</mp-jwt.version>
   </properties>
 
   <build>
     <defaultGoal>install</defaultGoal>
+    <finalName>moviefun</finalName>
 
     <plugins>
       <plugin>

http://git-wip-us.apache.org/repos/asf/tomee/blob/ebf29ec9/mp-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/mp-jwt/pom.xml b/mp-jwt/pom.xml
index a6cae6a..b1b86f6 100644
--- a/mp-jwt/pom.xml
+++ b/mp-jwt/pom.xml
@@ -27,10 +27,6 @@
   <packaging>jar</packaging>
   <name>OpenEJB :: Microprofile JWT</name>
 
-  <properties>
-    <mp-jwt.version>1.1-SNAPSHOT</mp-jwt.version>
-  </properties>
-
   <dependencies>
     <dependency>
       <groupId>org.apache.tomee</groupId>

http://git-wip-us.apache.org/repos/asf/tomee/blob/ebf29ec9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 82b50dd..ac36c1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -191,6 +191,9 @@
     <!-- arquillian related -->
     <version.arquillian.bom>1.1.13.Final</version.arquillian.bom>
     <version.shrinkwrap.resolver.bom>2.1.0</version.shrinkwrap.resolver.bom>
+
+    <mp-jwt.version>1.0</mp-jwt.version>
+    <mp-jwt-tck.version>${mp-jwt.version}</mp-jwt-tck.version>
   </properties>
 
   <build>

http://git-wip-us.apache.org/repos/asf/tomee/blob/ebf29ec9/tck/microprofile-tck/jwt/pom.xml
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/pom.xml b/tck/microprofile-tck/jwt/pom.xml
index 923c386..088e128 100644
--- a/tck/microprofile-tck/jwt/pom.xml
+++ b/tck/microprofile-tck/jwt/pom.xml
@@ -26,11 +26,6 @@
   <artifactId>microprofile-jwt-tck</artifactId>
   <name>OpenEJB :: TCK :: MicroProfile JWT TCK</name>
 
-
-  <properties>
-    <tck.version>1.1-SNAPSHOT</tck.version>
-  </properties>
-
   <dependencies>
 
     <dependency>
@@ -66,14 +61,14 @@
     <dependency>
       <groupId>org.eclipse.microprofile.jwt</groupId>
       <artifactId>microprofile-jwt-auth-tck</artifactId>
-      <version>${tck.version}</version>
+      <version>${mp-jwt-tck.version}</version>
     </dependency>
 
     <!-- This is the actual MP-JWT TCK test classes -->
     <dependency>
       <groupId>org.eclipse.microprofile.jwt</groupId>
       <artifactId>microprofile-jwt-auth-tck</artifactId>
-      <version>${tck.version}</version>
+      <version>${mp-jwt-tck.version}</version>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>


[8/8] tomee git commit: Merge remote-tracking branch 'apache/fb_tomee8' into TOMEE-2185_mp-jwt

Posted by jl...@apache.org.
Merge remote-tracking branch 'apache/fb_tomee8' into TOMEE-2185_mp-jwt


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

Branch: refs/heads/fb_tomee8
Commit: 6d591bbbdb4b36b3b9a58fe1fab199997e6725b3
Parents: 3e579aa f3c5c2d
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Apr 26 17:10:00 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Apr 26 17:10:00 2018 +0200

----------------------------------------------------------------------
 .../arquillian-tomee-webprofile-tests/pom.xml   |  6 ++
 .../openejb/arquillian/tests/ear/CodecBean.java | 32 +++++++++
 .../arquillian/tests/ear/CodecServlet.java      | 44 ++++++++++++
 .../tests/ear/EarCommonsCodecTest.java          | 73 ++++++++++++++++++++
 pom.xml                                         |  4 +-
 5 files changed, 157 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/6d591bbb/pom.xml
----------------------------------------------------------------------


[2/8] tomee git commit: Missing files from previous commit

Posted by jl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..feb2008
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
@@ -0,0 +1,92 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.principal;
+
+import org.apache.tomee.microprofile.jwt.ParseException;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+import org.jose4j.jwt.NumericDate;
+import org.jose4j.jwt.consumer.InvalidJwtException;
+import org.jose4j.jwt.consumer.JwtConsumer;
+import org.jose4j.jwt.consumer.JwtConsumerBuilder;
+import org.jose4j.jwt.consumer.JwtContext;
+
+/**
+ * A default implementation of the abstract JWTCallerPrincipalFactory that uses the Keycloak token parsing classes.
+ */
+public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory {
+
+    /**
+     * Tries to load the JWTAuthContextInfo from CDI if the class level authContextInfo has not been set.
+     */
+    public DefaultJWTCallerPrincipalFactory() {
+    }
+
+    @Override
+    public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException {
+        JWTCallerPrincipal principal;
+
+        try {
+            final JwtConsumerBuilder builder = new JwtConsumerBuilder()
+                    .setRequireExpirationTime()
+                    .setRequireSubject()
+                    .setSkipDefaultAudienceValidation()
+                    .setExpectedIssuer(authContextInfo.getIssuedBy())
+                    .setVerificationKey(authContextInfo.getSignerKey())
+                    .setJwsAlgorithmConstraints(
+                            new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
+                                    AlgorithmIdentifiers.RSA_USING_SHA256));
+
+            if (authContextInfo.getExpGracePeriodSecs() > 0) {
+                builder.setAllowedClockSkewInSeconds(authContextInfo.getExpGracePeriodSecs());
+
+            } else {
+                builder.setEvaluationTime(NumericDate.fromSeconds(0));
+            }
+
+            final JwtConsumer jwtConsumer = builder.build();
+            final JwtContext jwtContext = jwtConsumer.process(token);
+            final String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
+            //  Validate the JWT and process it to the Claims
+            jwtConsumer.processContext(jwtContext);
+            JwtClaims claimsSet = jwtContext.getJwtClaims();
+
+            // We have to determine the unique name to use as the principal name. It comes from upn, preferred_username, sub in that order
+            String principalName = claimsSet.getClaimValue("upn", String.class);
+            if (principalName == null) {
+                principalName = claimsSet.getClaimValue("preferred_username", String.class);
+                if (principalName == null) {
+                    principalName = claimsSet.getSubject();
+                }
+            }
+            claimsSet.setClaim(Claims.raw_token.name(), token);
+            principal = new DefaultJWTCallerPrincipal(token, type, claimsSet, principalName);
+
+        } catch (final InvalidJwtException e) {
+            throw new ParseException("Failed to verify token", e);
+
+        } catch (final MalformedClaimException e) {
+            throw new ParseException("Failed to verify token claims", e);
+        }
+
+        return principal;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
new file mode 100644
index 0000000..d8e3c4c
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
@@ -0,0 +1,59 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.principal;
+
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import java.util.Optional;
+
+/**
+ * An abstract CallerPrincipal implementation that provides access to the JWT claims that are required by
+ * the microprofile token.
+ */
+public abstract class JWTCallerPrincipal implements JsonWebToken {
+
+    private String name;
+
+    /**
+     * Create a JWTCallerPrincipal with the caller's name
+     *
+     * @param name - caller's name
+     */
+    public JWTCallerPrincipal(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Generate a human readable version of the caller principal and associated JWT.
+     *
+     * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+     *                JsonWebToken interface be displayed.
+     * @return human readable presentation of the caller principal and associated JWT.
+     */
+    public abstract String toString(final boolean showAll);
+
+    public <T> Optional<T> claim(final String claimName) {
+        final T claim = (T) getClaim(claimName);
+        return Optional.ofNullable(claim);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..e7ebcd6
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
@@ -0,0 +1,129 @@
+/*
+ *     Licensed to the Apache Software Foundation (ASF) under one or more
+ *     contributor license agreements.  See the NOTICE file distributed with
+ *     this work for additional information regarding copyright ownership.
+ *     The ASF licenses this file to You under the Apache License, Version 2.0
+ *     (the "License"); you may not use this file except in compliance with
+ *     the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *     Unless required by applicable law or agreed to in writing, software
+ *     distributed under the License is distributed on an "AS IS" BASIS,
+ *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *     See the License for the specific language governing permissions and
+ *     limitations under the License.
+ */
+package org.apache.tomee.microprofile.jwt.principal;
+
+import org.apache.tomee.microprofile.jwt.ParseException;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ServiceLoader;
+
+/**
+ * The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
+ */
+public abstract class JWTCallerPrincipalFactory {
+
+    private static JWTCallerPrincipalFactory instance;
+
+    /**
+     * Obtain the JWTCallerPrincipalFactory that has been set or by using the ServiceLoader pattern.
+     *
+     * @return the factory instance
+     * @see #setInstance(JWTCallerPrincipalFactory)
+     */
+    public static JWTCallerPrincipalFactory instance() {
+        if (instance == null) {
+            synchronized (JWTCallerPrincipalFactory.class) {
+                if (instance != null) {
+                    return instance;
+                }
+
+                ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                    @Override
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+                });
+                if (cl == null) {
+                    cl = JWTCallerPrincipalFactory.class.getClassLoader();
+                }
+
+                JWTCallerPrincipalFactory newInstance = loadSpi(cl);
+
+                if (newInstance == null && cl != JWTCallerPrincipalFactory.class.getClassLoader()) {
+                    cl = JWTCallerPrincipalFactory.class.getClassLoader();
+                    newInstance = loadSpi(cl);
+                }
+                if (newInstance == null) {
+                    throw new IllegalStateException("No JWTCallerPrincipalFactory implementation found!");
+                }
+
+                instance = newInstance;
+            }
+        }
+
+        return instance;
+    }
+
+    /**
+     * Look for a JWTCallerPrincipalFactory service implementation using the ServiceLoader.
+     *
+     * @param cl - the ClassLoader to pass into the {@link ServiceLoader#load(Class, ClassLoader)} method.
+     * @return the JWTCallerPrincipalFactory if found, null otherwise
+     */
+    private static JWTCallerPrincipalFactory loadSpi(ClassLoader cl) {
+        if (cl == null) {
+            return null;
+        }
+
+        // start from the root CL and go back down to the TCCL
+        JWTCallerPrincipalFactory instance = loadSpi(cl.getParent());
+
+        if (instance == null) {
+            ServiceLoader<JWTCallerPrincipalFactory> sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
+            URL u = cl.getResource("/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory");
+            System.out.printf("JWTCallerPrincipalFactory, cl=%s, u=%s, sl=%s\n", cl, u, sl);
+            try {
+                for (JWTCallerPrincipalFactory spi : sl) {
+                    if (instance != null) {
+                        throw new IllegalStateException(
+                                "Multiple JWTCallerPrincipalFactory implementations found: "
+                                        + spi.getClass().getName() + " and "
+                                        + instance.getClass().getName());
+                    } else {
+                        System.out.printf("sl=%s, loaded=%s\n", sl, spi);
+                        instance = spi;
+                    }
+                }
+
+            } catch (final Throwable e) {
+                System.err.printf("Warning: %s\n", e.getMessage());
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * Set the instance. It is used by OSGi environment where service loader pattern is not supported.
+     *
+     * @param resolver the instance to use.
+     */
+    public static void setInstance(final JWTCallerPrincipalFactory resolver) {
+        instance = resolver;
+    }
+
+    /**
+     * Parse the given bearer token string into a JWTCallerPrincipal instance.
+     *
+     * @param token - the bearer token provided for authorization
+     * @return A JWTCallerPrincipal representation for the token.
+     * @throws ParseException on parse or verification failure.
+     */
+    public abstract JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/resources/META-INF/org.apache.openejb.extension
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/resources/META-INF/org.apache.openejb.extension b/mp-jwt/src/main/resources/META-INF/org.apache.openejb.extension
new file mode 100644
index 0000000..9734019
--- /dev/null
+++ b/mp-jwt/src/main/resources/META-INF/org.apache.openejb.extension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.jaxrs.MPJWPProviderRegistration
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/mp-jwt/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..d5eea47
--- /dev/null
+++ b/mp-jwt/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.cdi.MPJWTCDIExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/mp-jwt/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
new file mode 100644
index 0000000..100e625
--- /dev/null
+++ b/mp-jwt/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.MPJWTInitializer
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/mp-jwt/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory b/mp-jwt/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
new file mode 100644
index 0000000..21c9831
--- /dev/null
+++ b/mp-jwt/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/tck/microprofile-tck/jwt/pom.xml
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/pom.xml b/tck/microprofile-tck/jwt/pom.xml
new file mode 100644
index 0000000..923c386
--- /dev/null
+++ b/tck/microprofile-tck/jwt/pom.xml
@@ -0,0 +1,197 @@
+<?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">
+  <parent>
+    <groupId>org.apache.tomee</groupId>
+    <artifactId>microprofile-tck</artifactId>
+    <version>8.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>microprofile-jwt-tck</artifactId>
+  <name>OpenEJB :: TCK :: MicroProfile JWT TCK</name>
+
+
+  <properties>
+    <tck.version>1.1-SNAPSHOT</tck.version>
+  </properties>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mp-jwt</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tomee</groupId>
+      <artifactId>tomee-catalina</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <!-- distro -->
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>apache-tomee</artifactId>
+      <version>${project.version}</version>
+      <type>zip</type>
+      <classifier>microprofile</classifier>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- This is the MP-JWT TCK base extension and utility classes -->
+    <dependency>
+      <groupId>org.eclipse.microprofile.jwt</groupId>
+      <artifactId>microprofile-jwt-auth-tck</artifactId>
+      <version>${tck.version}</version>
+    </dependency>
+
+    <!-- This is the actual MP-JWT TCK test classes -->
+    <dependency>
+      <groupId>org.eclipse.microprofile.jwt</groupId>
+      <artifactId>microprofile-jwt-auth-tck</artifactId>
+      <version>${tck.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <version>6.9.9</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>arquillian-tomee-remote</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.arquillian.testng</groupId>
+      <artifactId>arquillian-testng-core</artifactId>
+      <version>${version.arquillian}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.shrinkwrap.resolver</groupId>
+      <artifactId>shrinkwrap-resolver-api-maven</artifactId>
+      <version>2.2.2</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.shrinkwrap.resolver</groupId>
+      <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+      <version>2.2.2</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.shrinkwrap.resolver</groupId>
+      <artifactId>shrinkwrap-resolver-spi</artifactId>
+      <version>2.2.2</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-client</artifactId>
+      <version>${cxf.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.10</version>
+        <executions>
+          <execution>
+            <id>copy-tck-test-suite-file</id>
+            <phase>generate-test-sources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.eclipse.microprofile.jwt</groupId>
+                  <artifactId>microprofile-jwt-auth-tck</artifactId>
+                  <type>test-jar</type>
+                  <overWrite>true</overWrite>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.17</version>
+        <configuration>
+          <suiteXmlFiles>
+            <!-- TCK does not deliver the xml file for the moment -->
+            <suiteXmlFile>${project.build.directory}/test-classes/dev.xml</suiteXmlFile>
+          </suiteXmlFiles>
+          <systemProperties>
+            <!--<property>-->
+              <!--<name>validation.provider</name>-->
+              <!--<value>${validation.provider}</value>-->
+            <!--</property>-->
+          </systemProperties>
+          <parallel>methods</parallel>
+          <threadCount>4</threadCount>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>2.17</version>
+        <executions>
+          <execution>
+            <id>generate-test-report</id>
+            <phase>test</phase>
+            <goals>
+              <goal>report-only</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <outputDirectory>${project.build.directory}/surefire-reports</outputDirectory>
+          <outputName>test-report</outputName>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
new file mode 100644
index 0000000..cf4e837
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
@@ -0,0 +1,76 @@
+package org.apache.tomee.microprofile.jwt;
+
+import com.nimbusds.jose.JWSSigner;
+import org.apache.openejb.loader.JarLocation;
+import org.eclipse.microprofile.jwt.tck.TCKConstants;
+import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
+import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription;
+import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Node;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class AppDeploymentExtension implements LoadableExtension {
+    @Override
+    public void register(final ExtensionBuilder extensionBuilder) {
+        extensionBuilder.service(DeploymentScenarioGenerator.class, SimpleDeploymentScenarioGenerator.class);
+        extensionBuilder.service(ApplicationArchiveProcessor.class, MPJWTTCKArchiveProcess.class);
+    }
+
+    public static class SimpleDeploymentScenarioGenerator implements DeploymentScenarioGenerator {
+
+        private final DeploymentScenarioGenerator standard = new AnnotationDeploymentScenarioGenerator();
+        private final DeploymentDescription emptyTestWebApp;
+
+        public SimpleDeploymentScenarioGenerator() {
+            emptyTestWebApp = new DeploymentDescription("mp-jwt-tck.war",
+                    ShrinkWrap
+                            .create(WebArchive.class, "mp-jwt-tck.war")
+                            .addAsLibrary(JarLocation.jarLocation(TokenUtils.class))
+                            .addAsLibrary(JarLocation.jarLocation(JWSSigner.class))
+                            .addAsLibrary(JarLocation.jarLocation(TCKConstants.class).getAbsolutePath().replace("-tests.jar", "-test-sources.jar"))
+                            .add(EmptyAsset.INSTANCE, "WEB-INF/beans.xml"));
+        }
+
+
+        @Override
+        public List<DeploymentDescription> generate(final TestClass testClass) {
+            final List<DeploymentDescription> stdDeploymentDescriptions = standard.generate(testClass);
+
+            if (stdDeploymentDescriptions != null && !stdDeploymentDescriptions.isEmpty()) {
+                return stdDeploymentDescriptions;
+            }
+
+            return Collections.singletonList(emptyTestWebApp);
+        }
+    }
+
+    /**
+     * An ApplicationArchiveProcessor for the MP-JWT TCK if needed
+     * With the current implementation we don't need to do anything
+     */
+    public static class MPJWTTCKArchiveProcess implements ApplicationArchiveProcessor {
+        private static Logger log = Logger.getLogger(MPJWTTCKArchiveProcess.class.getName());
+
+        @Override
+        public void process(final Archive<?> appArchive, final TestClass testClass) {
+            if (!(appArchive instanceof WebArchive)) {
+                return;
+            }
+            WebArchive war = WebArchive.class.cast(appArchive);
+
+            log.info("Augmented war: \n"+war.toString(true));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..98a4867
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.AppDeploymentExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/tck/microprofile-tck/jwt/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/resources/arquillian.xml b/tck/microprofile-tck/jwt/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..8e7a66b
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/test/resources/arquillian.xml
@@ -0,0 +1,39 @@
+<?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"
+    xsi:schemaLocation="
+      http://jboss.org/schema/arquillian
+      http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+  <container qualifier="tomee" default="true">
+    <configuration>
+      <property name="catalina_opts">-Xmx512m -XX:MaxPermSize=512m</property>
+      <property name="httpPort">-1</property>
+      <property name="stopPort">-1</property>
+      <property name="ajpPort">-1</property>
+      <property name="classifier">microprofile</property>
+      <property name="debug">false</property>
+      <property name="dir">target/tomee-tck</property>
+      <property name="appWorkingDir">target/tck-workdir</property>
+      <property name="simpleLog">true</property>
+      <property name="properties"></property>
+    </configuration>
+  </container>
+</arquillian>

http://git-wip-us.apache.org/repos/asf/tomee/blob/def443a4/tck/microprofile-tck/jwt/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/resources/dev.xml b/tck/microprofile-tck/jwt/src/test/resources/dev.xml
new file mode 100644
index 0000000..00741d1
--- /dev/null
+++ b/tck/microprofile-tck/jwt/src/test/resources/dev.xml
@@ -0,0 +1,93 @@
+<?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.
+  -->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<suite name="microprofile-jwt-auth-FullTCK" verbose="1" preserve-order="true" configfailurepolicy="continue" >
+
+  <!-- The required base JAX-RS and CDI based tests that all MP-JWT implementations
+  must pass.
+  -->
+
+  <test name="base-tests" verbose="10">
+    <groups>
+      <define name="base-groups">
+        <include name="arquillian" description="Arquillian internal"/>
+        <include name="utils" description="Utility tests"/>
+        <include name="jwt" description="Base JsonWebToken tests"/>
+        <include name="jaxrs" description="JAX-RS invocation tests"/>
+        <include name="cdi" description="Base CDI injection of ClaimValues"/>
+        <include name="cdi-json" description="CDI injection of JSON-P values"/>
+        <include name="cdi-provider" description="CDI injection of javax.inject.Provider values"/>
+      </define>
+      <define name="excludes">
+        <include name="debug" description="Internal debugging tests" />
+      </define>
+      <run>
+        <include name="base-groups" />
+        <exclude name="excludes" />
+      </run>
+    </groups>
+    <classes>
+      <class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RequiredClaimsTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.PrimitiveInjectionTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
+      <!--
+      -->
+    </classes>
+  </test>
+
+  <test name="extended-tests" verbose="10">
+    <groups>
+      <define name="extended-groups">
+        <include name="arquillian" description="Arquillian internal"/>
+        <include name="ejb-optional" description="EJB container integration tests"/>
+        <include name="jacc-optional" description="JACC API integration tests"/>
+        <include name="servlet-optional" description="Servlet container integration tests"/>
+        <include name="ee-security-optional" description="Java EE security feature tests"/>
+      </define>
+      <define name="excludes">
+        <include name="debug" description="Internal debugging tests" />
+      </define>
+      <run>
+        <include name="extended-groups" />
+        <exclude name="excludes" />
+      </run>
+    </groups>
+    <classes>
+      <class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" >
+        <methods>
+          <!-- Excluded cause we never really enforce ACC context for EJB Calls in TomEE -->
+          <exclude name="getSubjectClass"/>
+        </methods>
+      </class>
+
+      <class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
+      <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
+      <!--
+      -->
+    </classes>
+  </test>
+</suite>


[7/8] tomee git commit: No need for the UI part here

Posted by jl...@apache.org.
No need for the UI part here


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

Branch: refs/heads/fb_tomee8
Commit: 3e579aad22e21cf239604e00bcb6a3b22646f6c8
Parents: ebf29ec
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Mon Apr 23 15:01:15 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Mon Apr 23 15:01:15 2018 +0200

----------------------------------------------------------------------
 .../rest-mp-jwt/src/main/webapp/WEB-INF/web.xml |  46 -----
 .../rest-mp-jwt/src/main/webapp/app/app.less    |  62 ------
 .../rest-mp-jwt/src/main/webapp/app/config.js   |  45 -----
 .../src/main/webapp/app/js/application.js       | 193 -------------------
 .../rest-mp-jwt/src/main/webapp/app/js/i18n.js  |  66 -------
 .../rest-mp-jwt/src/main/webapp/app/js/id.js    |  43 -----
 .../rest-mp-jwt/src/main/webapp/app/js/log.js   |  40 ----
 .../src/main/webapp/app/js/model/movie.js       |  48 -----
 .../src/main/webapp/app/js/model/movies.js      |  35 ----
 .../rest-mp-jwt/src/main/webapp/app/js/start.js |  29 ---
 .../src/main/webapp/app/js/templates.js         |  69 -------
 ...pplication-table-paginator-button.handlebars |   1 -
 .../templates/application-table-row.handlebars  |   8 -
 .../app/js/templates/application.handlebars     |  50 -----
 .../app/js/templates/container.handlebars       |  10 -
 .../app/js/templates/load-data-link.handlebars  |   1 -
 .../webapp/app/js/templates/movie.handlebars    |  56 ------
 .../app/js/view/application-table-paginator.js  |  77 --------
 .../webapp/app/js/view/application-table-row.js |  63 ------
 .../src/main/webapp/app/js/view/application.js  | 135 -------------
 .../src/main/webapp/app/js/view/container.js    |  62 ------
 .../src/main/webapp/app/js/view/movie.js        |  75 -------
 examples/rest-mp-jwt/src/main/webapp/index.jsp  |  36 ----
 23 files changed, 1250 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml b/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 328247d..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,46 +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.
--->
-
-<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
-  <welcome-file-list>
-    <welcome-file>index.jsp</welcome-file>
-  </welcome-file-list>
-
-  <!-- The trick is to put all your static files under the same directory and map the "default" servlet to it -->
-  <servlet-mapping>
-    <servlet-name>default</servlet-name>
-    <url-pattern>/app/*</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>default</servlet-name>
-    <url-pattern>/webjars/*</url-pattern>
-  </servlet-mapping>
-
-  <!-- Any other request will point to the "index.jsp" page. This way Backbone knows how to manage page transitions
-   at the client side in case the user starts the application from a permalink. -->
-  <servlet>
-    <servlet-name>application</servlet-name>
-    <jsp-file>/index.jsp</jsp-file>
-  </servlet>
-  <servlet-mapping>
-    <servlet-name>application</servlet-name>
-    <url-pattern>/*</url-pattern>
-  </servlet-mapping>
-
-</web-app>
-

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/app.less
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/app.less b/examples/rest-mp-jwt/src/main/webapp/app/app.less
deleted file mode 100644
index 61fd5e2..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/app.less
+++ /dev/null
@@ -1,62 +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.
- */
-
-body {
-  @content-margin-top: 80px;
-
-  .ux-movie-window {
-    .modal-dialog {
-      padding-top: 90px;
-      padding-bottom: 0px;
-    }
-  }
-
-  .ux-landing {
-    margin-top: @content-margin-top;
-  }
-
-  .ux-setup {
-    margin-top: @content-margin-top;
-  }
-
-  .ux-application {
-    margin-top: @content-margin-top;
-
-    .pagination {
-      margin-top: 0px;
-      margin-bottom: 0px;
-    }
-
-    th:last-child {
-      width: 5px;
-    }
-
-    .ux-add-btn {
-      position: absolute;
-      bottom: 20px;
-      right: 30px;
-    }
-
-    a.ux-delete-row:hover, a.ux-edit-row:hover {
-      cursor: hand;
-    }
-
-    .panel-body>.input-group {
-      margin-bottom: 15px;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/config.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/config.js b/examples/rest-mp-jwt/src/main/webapp/app/config.js
deleted file mode 100644
index bbdc5e1..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/config.js
+++ /dev/null
@@ -1,45 +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.
- */
-
-var APP_CONFIG = {
-    baseUrl: window.ux.ROOT_URL,
-    paths: {
-        'text': 'webjars/requirejs-text/2.0.10/text',
-        'lib/less': 'webjars/less/1.6.0/less.min',
-        'lib/jquery': 'webjars/jquery/2.1.0/jquery.min',
-        'lib/bootstrap': 'webjars/bootstrap/3.1.0/js/bootstrap.min',
-        'lib/handlebars': 'webjars/handlebars/1.2.1/handlebars.min',
-        'lib/underscore': 'webjars/underscorejs/1.4.3/underscore-min',
-        'lib/json2': 'webjars/json2/20110223/json2.min',
-        'lib/backbone': 'webjars/backbonejs/1.0.0/backbone'
-    },
-    shim: {
-        'lib/bootstrap': {
-            deps: ['lib/jquery']
-        },
-        'lib/underscore': {
-            exports: '_'
-        },
-        'lib/backbone': {
-            deps: ['lib/jquery', 'lib/json2', 'lib/underscore']
-        },
-        'app/js/templates': {
-            deps: ['lib/underscore', 'app/js/i18n']
-        }
-    }
-};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/application.js b/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
deleted file mode 100644
index 9ec4cab..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/application.js
+++ /dev/null
@@ -1,193 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = [
-        'app/js/view/container',
-        'app/js/view/application',
-        'app/js/view/application-table-paginator',
-        'app/js/view/movie',
-        'lib/underscore',
-        'app/js/model/movies',
-        'app/js/model/movie',
-        'app/js/i18n',
-        'lib/less', 'lib/backbone', 'lib/jquery', 'lib/bootstrap'
-    ];
-    define(deps, function (containerView, applicationView, paginator, MovieView, underscore, moviesList, MovieModel) {
-        var max = 5;
-        var appState = {
-            page: null,
-            fieldName: null,
-            fieldValue: null
-        };
-        containerView.render();
-
-        $.ajaxSetup({ cache: false });
-
-        function loadPage(pageNumber, fieldName, fieldValue) {
-            var data = {
-                max: max,
-                first: ((pageNumber - 1) * max)
-            };
-            if (fieldName && fieldValue) {
-                data.field = fieldName;
-                data.searchTerm = fieldValue;
-            }
-            applicationView.setFilter(fieldName, fieldValue);
-            moviesList.fetch({
-                data: data,
-                success: function (result) {
-                    applicationView.addRows(result.models);
-
-                    $.ajax({
-                        url: window.ux.ROOT_URL + 'rest/movies/count/',
-                        method: 'GET',
-                        dataType: 'json',
-                        data: {
-                            field: appState.fieldName,
-                            searchTerm: appState.fieldValue
-                        },
-                        success: function (total) {
-                            var count = Math.ceil(total / max);
-                            paginator.setCount(count);
-                            applicationView.setPaginator(count);
-                        }
-                    });
-                }
-            });
-        }
-
-        function start() {
-            //Starting the backbone router.
-            var Router = Backbone.Router.extend({
-                routes: {
-                    '': 'showApplication',
-                    'application': 'showApplication',
-                    'application/:page': 'showApplication',
-                    'application/:page/:field/:value': 'showApplication'
-                },
-
-                showApplication: function (page, fieldName, fieldValue) {
-                    var me = this;
-                    appState.page = page;
-                    appState.fieldName = fieldName;
-                    appState.fieldValue = fieldValue;
-                    containerView.showView(applicationView);
-                    if (!page || !underscore.isNumber(Number(page))) {
-                        me.showApplication(1);
-                    } else {
-                        loadPage(Number(page), fieldName, fieldValue);
-                        if (fieldName) {
-                            me.navigate('application/' + page + '/' + fieldName + '/' + fieldValue, {
-                                trigger: false
-                            });
-                        } else {
-                            me.navigate('application/' + page, {
-                                trigger: false
-                            });
-                        }
-                    }
-                }
-            });
-            var router = new Router();
-
-            applicationView.on('load-sample', function () {
-                $.ajax({
-                    url: window.ux.ROOT_URL + 'rest/load/',
-                    method: 'POST',
-                    dataType: 'json',
-                    data: {},
-                    success: function (data) {
-                        router.showApplication();
-                    }
-                });
-            });
-
-            applicationView.on('delete', function (data) {
-                data.model.destroy({
-                    success: function () {
-                        router.showApplication(appState.page, appState.fieldName, appState.fieldValue);
-                    }
-                });
-            });
-
-            function showMovieWindow(model) {
-                var view = new MovieView({
-                    model: model
-                });
-                view.render();
-                view.on('save-model', function (data) {
-                    data.model.save({}, {
-                        success: function () {
-                            view.remove();
-                            loadPage(appState.page, appState.fieldName, appState.fieldValue);
-                        }
-                    });
-                });
-                $('body').append(view.$el);
-                view.$el.modal({});
-            }
-
-            applicationView.on('add', function () {
-                showMovieWindow(new MovieModel({}));
-            });
-
-            applicationView.on('edit', function (data) {
-                showMovieWindow(data.model);
-            });
-
-            applicationView.on('filter', function (data) {
-                router.navigate('application/1/' + data.filterType + '/' + data.filterValue, {
-                    trigger: true
-                });
-            });
-
-            applicationView.on('clear-filter', function (data) {
-                router.navigate('application/1', {
-                    trigger: true
-                });
-            });
-
-            paginator.on('go-to-page', function (data) {
-                var page = data.number;
-                if (page === 'last') {
-                    page = paginator.getCount();
-                }
-                router.showApplication(page, appState.fieldName, appState.fieldValue);
-            });
-
-            //Starting the backbone history.
-            Backbone.history.start({
-                pushState: true,
-                root: window.ux.ROOT_URL // This value is set by <c:url>
-            });
-
-            return {
-                getRouter: function () {
-                    return router;
-                }
-            };
-        }
-
-        return {
-            start: start
-        };
-    });
-}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js b/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
deleted file mode 100644
index 2603dec..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/i18n.js
+++ /dev/null
@@ -1,66 +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.
- "use strict";
- */
-
-define(['lib/underscore', 'lib/handlebars', 'app/js/log'], function (underscore) {
-    'use strict';
-
-    var missing = Handlebars.compile('[!{{key}}!]');
-    var messages = {
-        'application.name': 'Moviefun',
-        'load.dada': 'Click here to load sample data',
-        'movies': 'Movies',
-        'title': 'Title',
-        'director': 'Director',
-        'genre': 'Genre',
-        'rating': 'Rating',
-        'year': 'Year',
-        'add.movie': 'Add movie',
-        'movie': 'Movie',
-        'close': 'Close',
-        'save': 'Save',
-
-        'dummy': ''
-    };
-
-    underscore.each(underscore.keys(messages), function (key) {
-        var template = Handlebars.compile(messages[key]);
-        messages[key] = template;
-    });
-
-    var get = function (key, values) {
-        var template = messages[key];
-        var cfg = values;
-        if (!template) {
-            template = missing;
-            cfg = {
-                key: key
-            };
-            window.console.error('Missing i18n message.', key);
-        }
-        return template(cfg);
-    };
-
-    Handlebars.registerHelper('i18n', function (key) {
-        return get(key);
-    });
-
-    return {
-        get: get
-    };
-});

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/id.js b/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
deleted file mode 100644
index fc4c56a..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/id.js
+++ /dev/null
@@ -1,43 +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.
- "use strict";
- */
-
-define(['lib/underscore', 'lib/handlebars'], function (underscore) {
-    'use strict';
-
-    var value = underscore.uniqueId('moviefun_');
-
-    var current = function () {
-        return value;
-    };
-    var next = function () {
-        value = underscore.uniqueId('moviefun_');
-        return value;
-    };
-    Handlebars.registerHelper('id_current', function (key) {
-        return current();
-    });
-    Handlebars.registerHelper('id_next', function (key) {
-        return next();
-    });
-
-    return {
-        current: current,
-        next: next
-    };
-});

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/log.js b/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
deleted file mode 100644
index 6e79b98..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/log.js
+++ /dev/null
@@ -1,40 +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.
- */
-
-define([], function () {
-    'use strict';
-
-    var noOp = function () {
-        return ''; // no-op
-    };
-
-    if (!window.console) {
-        window.console = {};
-    }
-
-    function createIfNull(functionName) {
-        if (!window.console[functionName]) {
-            window.console[functionName] = noOp;
-        }
-    }
-
-    createIfNull('error');
-    createIfNull('warn');
-    createIfNull('log');
-    createIfNull('info');
-});

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
deleted file mode 100644
index 36be222..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movie.js
+++ /dev/null
@@ -1,48 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['lib/backbone'];
-    define(deps, function () {
-        var isString = function (obj) {
-            return Object.prototype.toString.call(obj) === '[object String]';
-        };
-        return Backbone.Model.extend({
-            urlRoot: window.ux.ROOT_URL + 'rest/movies',
-            idAttribute: 'id',
-            toJSON: function () {
-                if (!!this.attributes.rating && isString(this.attributes.rating)) {
-                    this.attributes.rating = parseInt(this.attributes.rating, 10);
-                }
-                if (!!this.attributes.year && isString(this.attributes.year)) {
-                    this.attributes.year = parseInt(this.attributes.year, 10);
-                }
-                if (!!this.attributes.id && isString(this.attributes.id)) {
-                    this.attributes.id = parseInt(this.attributes.id, 10);
-                }
-                return this.attributes;
-            },
-            defaults: {
-                rating: 5,
-                year: new Date().getFullYear()
-            }
-        });
-    });
-}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js b/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
deleted file mode 100644
index 828d2f8..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/model/movies.js
+++ /dev/null
@@ -1,35 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/model/movie', 'lib/backbone'];
-    define(deps, function (Movie) {
-        var Cls = Backbone.Collection.extend({
-            model: Movie,
-            url: window.ux.ROOT_URL + 'rest/movies',
-            parse: function (response) {
-                return response;
-            }
-        });
-        return new Cls();
-    });
-}());
-
-

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/start.js b/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
deleted file mode 100644
index 33f7fbd..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/start.js
+++ /dev/null
@@ -1,29 +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.
- */
-
-require.config(APP_CONFIG);
-
-requirejs(['app/js/application'], function (app) {
-    'use strict';
-
-    $(window.document).ready(function () {
-        // all the action is in app
-        app.start();
-    });
-});
-

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js b/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
deleted file mode 100644
index e3f3300..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates.js
+++ /dev/null
@@ -1,69 +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.
- */
-
-(function () {
-    'use strict';
-
-    var files = [
-        'container',
-        'application',
-        'application-table-row',
-        'application-table-paginator-button',
-        'load-data-link',
-        'movie'
-    ];
-
-    function loop(values, callback) {
-        var index;
-        for (index = 0; index < values.length; index += 1) {
-            callback(values[index], index);
-        }
-    }
-
-    // Preparing the "requirements" paths.
-    var requirements = [];
-    loop(files, function (file) {
-        requirements.push('text!app/js/templates/' + file + '.handlebars');
-    });
-
-    define(requirements, function () {
-        var templates = {};
-
-        var myArgs = arguments;
-        loop(files, function (file, i) {
-            templates[file] = Handlebars.compile(myArgs[i]);
-        });
-
-        return {
-            getValue: function (templateName, cfg) {
-                var template = templates[templateName];
-                if (!template) {
-                    throw 'Template not registered. "' + templateName + '"';
-                }
-                var result;
-                if (cfg) {
-                    result = template(cfg);
-                } else {
-                    result = template({});
-                }
-                return result;
-            }
-        };
-    });
-}());
-

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
deleted file mode 100644
index 0031aba..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-paginator-button.handlebars
+++ /dev/null
@@ -1 +0,0 @@
-<li><a href="{{pageNumber}}">{{pageText}}</a></li>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
deleted file mode 100644
index dc9bf7c..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application-table-row.handlebars
+++ /dev/null
@@ -1,8 +0,0 @@
-<td><a href="edit" class="ux-edit-row">{{title}}</a></td>
-<td>{{director}}</td>
-<td>{{genre}}</td>
-<td>{{rating}}</td>
-<td>{{year}}</td>
-<td>
-    <a href="delete" class="ux-delete-row"><span class="glyphicon glyphicon-trash"></span></a>
-</td>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
deleted file mode 100644
index f15d1a9..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/application.handlebars
+++ /dev/null
@@ -1,50 +0,0 @@
-<div class="row">
-    <div class="col-md-12">
-        <div class="panel panel-default">
-            <div class="panel-heading">
-                <h3 class="panel-title">{{i18n "movies"}}</h3>
-            </div>
-            <div class="panel-body">
-                <div class="input-group">
-                    <div class="input-group-btn">
-                        <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
-                            <span class="ux-selected-filter">{{i18n "title"}}</span> <span class="caret"></span>
-                        </button>
-                        <ul class="dropdown-menu" role="menu">
-                            <li><a href="title" class="ux-filter">{{i18n "title"}}</a></li>
-                            <li><a href="director" class="ux-filter">{{i18n "director"}}</a></li>
-                            <li><a href="genre" class="ux-filter">{{i18n "genre"}}</a></li>
-                            <li><a href="rating" class="ux-filter">{{i18n "rating"}}</a></li>
-                            <li><a href="year" class="ux-filter">{{i18n "year"}}</a></li>
-                        </ul>
-                    </div><!-- /btn-group -->
-                    <input type="text" class="form-control ux-filter-field">
-                    <span class="input-group-btn">
-                        <button class="btn btn-primary ux-clear-filter-action" type="button">
-                            <span class="glyphicon glyphicon-remove-circle"></span>
-                        </button>
-                        <button class="btn btn-primary ux-filter-action" type="button">
-                            <span class="glyphicon glyphicon-search"></span>
-                        </button>
-                    </span>
-                </div>
-                <table class="table table-bordered table-striped table-hover">
-                    <thead>
-                    <tr>
-                        <th>{{i18n "title"}}</th>
-                        <th>{{i18n "director"}}</th>
-                        <th>{{i18n "genre"}}</th>
-                        <th>{{i18n "rating"}}</th>
-                        <th>{{i18n "year"}}</th>
-                        <th></th>
-                    </tr>
-                    </thead>
-                    <tbody></tbody>
-                </table>
-                <button type="button" class="btn btn-primary ux-add-btn">{{i18n "add.movie"}}</button>
-            </div>
-        </div>
-    </div>
-</div>
-
-

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
deleted file mode 100644
index dba60dd..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/container.handlebars
+++ /dev/null
@@ -1,10 +0,0 @@
-<div class="navbar navbar-inverse navbar-fixed-top">
-    <div class="container">
-        <div class="navbar-header">
-            <a class="navbar-brand" href="#">{{i18n "application.name"}}</a>
-        </div>
-    </div>
-</div>
-<div class="container">
-    <div class="ux-contentarea"></div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
deleted file mode 100644
index 1785578..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/load-data-link.handlebars
+++ /dev/null
@@ -1 +0,0 @@
-<a href="load-data">{{i18n "load.dada"}}</a>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars b/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
deleted file mode 100644
index 97c511c..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/templates/movie.handlebars
+++ /dev/null
@@ -1,56 +0,0 @@
-<div class="modal-dialog">
-    <div class="modal-content">
-        <div class="modal-header">
-            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-            <h4 class="modal-title">{{i18n "movie"}}</h4>
-        </div>
-        <div class="modal-body">
-            <form class="form-horizontal" role="form">
-                <div class="form-group">
-                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "title"}}</label>
-
-                    <div class="col-lg-10">
-                        <input class="form-control ux-title" id="{{id_current}}" placeholder="{{i18n 'title'}}"
-                               type="text" value="{{title}}">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "director"}}</label>
-
-                    <div class="col-lg-10">
-                        <input class="form-control ux-director" id="{{id_current}}"
-                               type="text" placeholder="{{i18n 'director'}}" value="{{director}}">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "genre"}}</label>
-
-                    <div class="col-lg-10">
-                        <input class="form-control ux-genre" id="{{id_current}}" placeholder="{{i18n 'genre'}}"
-                               type="text" value="{{genre}}">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "rating"}}</label>
-
-                    <div class="col-lg-10">
-                        <input class="form-control ux-rating" id="{{id_current}}"
-                               type="number" min="0" max="10" placeholder="{{i18n 'rating'}}" value="{{rating}}">
-                    </div>
-                </div>
-                <div class="form-group">
-                    <label for="{{id_next}}" class="col-lg-2 control-label">{{i18n "year"}}</label>
-
-                    <div class="col-lg-10">
-                        <input class="form-control ux-year" id="{{id_current}}" placeholder="{{i18n 'year'}}"
-                               type="number" min="1900" max="{{currentYear}}" value="{{year}}">
-                    </div>
-                </div>
-            </form>
-        </div>
-        <div class="modal-footer">
-            <button type="button" class="btn btn-default ux-close" data-dismiss="modal">{{i18n "close"}}</button>
-            <button type="button" class="btn btn-primary ux-save" data-dismiss="modal">{{i18n "save"}}</button>
-        </div>
-    </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
deleted file mode 100644
index c5d2422..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-paginator.js
+++ /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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/templates', 'lib/backbone'];
-    define(deps, function (templates) {
-
-        var View = Backbone.View.extend({
-            tagName: 'ul',
-            className: 'pagination',
-
-            count: 0,
-
-            events: {
-                'click a': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    var myLink = $(evt.target);
-                    var href = myLink.attr('href');
-                    me.trigger('go-to-page', {
-                        number: href
-                    });
-                }
-            },
-
-            render: function () {
-                var me = this;
-                me.$el.empty();
-                me.$el.append(templates.getValue('application-table-paginator-button', {
-                    pageNumber: '1',
-                    pageText: '<<'
-                }));
-                var i;
-                for (i = 1; i < me.count + 1; i += 1) {
-                    me.$el.append(templates.getValue('application-table-paginator-button', {
-                        pageNumber: i,
-                        pageText: i
-                    }));
-                }
-                me.$el.append(templates.getValue('application-table-paginator-button', {
-                    pageNumber: 'last',
-                    pageText: '>>'
-                }));
-                return this;
-            },
-
-            setCount: function (count) {
-                var me = this;
-                me.count = count;
-                me.render();
-            },
-
-            getCount: function () {
-                var me = this;
-                return me.count;
-            }
-        });
-        return new View().render();
-    });
-}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
deleted file mode 100644
index 771a062..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application-table-row.js
+++ /dev/null
@@ -1,63 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/templates', 'lib/backbone'];
-    define(deps, function (templates) {
-
-        var View = Backbone.View.extend({
-            tagName: 'tr',
-            events: {
-                'click .ux-delete-row': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('delete', {
-                        model: me.model
-                    });
-                    me.remove();
-                },
-                'click .ux-edit-row': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('edit', {
-                        model: me.model
-                    });
-                }
-            },
-
-            render: function () {
-                var me = this;
-                if (!this.options.isRendered) {
-                    me.$el.empty();
-                    me.$el.append(templates.getValue('application-table-row', {
-                        title: me.model.get('title'),
-                        director: me.model.get('director'),
-                        genre: me.model.get('genre'),
-                        rating: me.model.get('rating'),
-                        year: me.model.get('year')
-                    }));
-                    me.options.isRendered = true;
-                }
-                return this;
-            }
-        });
-        return View;
-    });
-}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
deleted file mode 100644
index 7dae6b3..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/view/application.js
+++ /dev/null
@@ -1,135 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/templates', 'app/js/view/application-table-row', 'app/js/view/application-table-paginator',
-        'lib/underscore', 'app/js/i18n', 'lib/backbone'];
-    define(deps, function (templates, TableRowView, paginator, underscore, i18n) {
-
-        var View = Backbone.View.extend({
-            tagName: 'div',
-            className: 'ux-application',
-
-            loadDataLink: $(templates.getValue('load-data-link', {})),
-
-            filterOption: 'title',
-
-            events: {
-                'click .ux-filter': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    var selected = $(me.$el.find('.ux-selected-filter').get(0));
-                    var myLink = $(evt.target);
-                    me.filterOption = myLink.attr('href');
-                    selected.html(i18n.get(me.filterOption, {}));
-                },
-                'click .ux-filter-action': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    var filterValue = $(me.$el.find('.ux-filter-field').get(0)).val();
-                    filterValue = $.trim(filterValue);
-                    if (filterValue !== '') {
-                        me.trigger('filter', {
-                            filterType: me.filterOption,
-                            filterValue: filterValue
-                        });
-                    }
-                },
-                'click .ux-clear-filter-action': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('clear-filter', {});
-                },
-                'click .ux-application': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('navigate', {
-                        path: 'application'
-                    });
-                },
-                'click .ux-add-btn': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('add', {});
-                }
-            },
-
-            setFilter: function (fieldName, fieldValue) {
-                var field = fieldName;
-                var value = fieldValue;
-                if (!fieldName || $.trim(fieldName) === '') {
-                    field = 'title';
-                    value = '';
-                }
-                var me = this;
-                me.filterOption = field;
-                $(me.$el.find('.ux-selected-filter').get(0)).html(i18n.get(me.filterOption, {}));
-                $(me.$el.find('.ux-filter-field').get(0)).val(value);
-            },
-
-            render: function () {
-                var me = this;
-                if (!this.options.isRendered) {
-                    me.$el.empty();
-                    me.$el.append(templates.getValue('application', {}));
-                    me.loadDataLink.on('click', function (evt) {
-                        evt.preventDefault();
-                        me.trigger('load-sample', {});
-                    });
-                    me.options.isRendered = true;
-                }
-                return this;
-            },
-
-            addRows: function (rows) {
-                var me = this;
-                var tbody = $(me.$el.find('tbody').get(0));
-                tbody.empty();
-                paginator.$el.detach();
-                me.loadDataLink.detach();
-                underscore.each(rows, function (model) {
-                    var row = new TableRowView({
-                        model: model
-                    });
-                    row.on('delete', function (data) {
-                        me.trigger('delete', data);
-                    });
-                    row.on('edit', function (data) {
-                        me.trigger('edit', data);
-                    });
-                    tbody.append(row.render().$el);
-                });
-            },
-
-            setPaginator: function (count) {
-                var me = this;
-                paginator.$el.detach();
-                me.loadDataLink.detach();
-                var table = $(me.$el.find('.table').get(0));
-                if (count) {
-                    table.after(paginator.$el);
-                } else {
-                    table.after(me.loadDataLink);
-                }
-            }
-        });
-        return new View();
-    });
-}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
deleted file mode 100644
index 73a57f1..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/view/container.js
+++ /dev/null
@@ -1,62 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/templates', 'app/js/i18n', 'lib/backbone'];
-    define(deps, function (templates) {
-
-        var View = Backbone.View.extend({
-            el: 'body',
-
-            showView: function (view) {
-                var me = this;
-                var contentarea = me.$('.ux-contentarea');
-                if (me.currentView) {
-                    me.currentView.$el.detach();
-                }
-                me.currentView = view;
-                me.currentView.render();
-                contentarea.append(me.currentView.el);
-                if (view.renderCallback) {
-                    view.renderCallback();
-                }
-                me.$('.ux-app-menu-item').removeClass('active');
-                var myMenuItem = me.$('li.ux-app-menu-item.' + view.className);
-                myMenuItem.addClass('active');
-            },
-
-            render: function () {
-                if (this.options.isRendered) {
-                    return this;
-                }
-                var html = templates.getValue('container', {
-                    userName: ''
-                });
-                this.$el.html(html);
-
-                // render it only once
-                this.options.isRendered = true;
-                return this;
-            }
-        });
-
-        return new View({});
-    });
-}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js b/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
deleted file mode 100644
index 0417945..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/app/js/view/movie.js
+++ /dev/null
@@ -1,75 +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.
- */
-
-(function () {
-    'use strict';
-
-    var deps = ['app/js/templates', 'lib/underscore', 'lib/backbone', 'app/js/id'];
-    define(deps, function (templates, underscore) {
-
-        var View = Backbone.View.extend({
-            tagName: 'div',
-            className: 'modal ux-movie-window',
-            events: {
-                'click .ux-application': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.trigger('show-application', {});
-                },
-                'click .ux-close': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    me.remove();
-                },
-                'click .ux-save': function (evt) {
-                    evt.preventDefault();
-                    var me = this;
-                    var model = me.model;
-
-                    function set(name) {
-                        var field = $(me.$el.find('.ux-' + name).get(0));
-                        model.set(name, field.val());
-                    }
-
-                    set('title');
-                    set('director');
-                    set('genre');
-                    set('rating');
-                    set('year');
-                    me.trigger('save-model', {
-                        model: model
-                    });
-                }
-            },
-            render: function () {
-                var me = this;
-                me.$el.empty();
-                me.$el.append(templates.getValue('movie', {
-                    title: me.model.get('title'),
-                    director: me.model.get('director'),
-                    genre: me.model.get('genre'),
-                    rating: me.model.get('rating'),
-                    year: me.model.get('year'),
-                    currentYear: new Date().getFullYear()
-                }));
-                return me;
-            }
-        });
-        return View;
-    });
-}());

http://git-wip-us.apache.org/repos/asf/tomee/blob/3e579aad/examples/rest-mp-jwt/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/examples/rest-mp-jwt/src/main/webapp/index.jsp b/examples/rest-mp-jwt/src/main/webapp/index.jsp
deleted file mode 100644
index 63d3e42..0000000
--- a/examples/rest-mp-jwt/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<!--
-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.
--->
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
-<html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>Moviefun</title>
-  <link href="<c:url value='/webjars/bootstrap/3.1.0/css/bootstrap.min.css'/>" rel="stylesheet">
-  <link href="<c:url value='/app/app.less'/>" rel="stylesheet/less" type="text/css">
-  <script src="<c:url value='/webjars/requirejs/2.1.10/require.min.js'/>"></script>
-  <script type="text/javascript">
-    window.ux = window.ux || {};
-    window.ux.SESSION_ID = "<%=request.getSession().getId()%>";
-    window.ux.ROOT_URL = "<c:url value='/'/>".replace(';jsessionid=' + window.ux.SESSION_ID, '');
-  </script>
-  <script src="<c:url value='/app/config.js'/>"></script>
-  <script src="<c:url value='/app/js/start.js'/>"></script>
-</head>
-<body></body>
-</html>
\ No newline at end of file