tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jgallim...@apache.org
Subject [27/50] [abbrv] tomee git commit: Make a simple test case to wire up everything and start adding a simple UI on top
Date Thu, 26 Jul 2018 10:18:42 GMT
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));
         }


Mime
View raw message