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/16 23:56:09 UTC

[1/4] tomee git commit: Some refactoring to remove Java 8 lambdas

Repository: tomee
Updated Branches:
  refs/heads/master 09ca434d9 -> 387c11af0


http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
deleted file mode 100644
index 661fbde..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
+++ /dev/null
@@ -1,360 +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.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

http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
deleted file mode 100644
index feb2008..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
+++ /dev/null
@@ -1,92 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
deleted file mode 100644
index d8e3c4c..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
+++ /dev/null
@@ -1,59 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
deleted file mode 100644
index e7ebcd6..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
+++ /dev/null
@@ -1,129 +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.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/72c08321/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml b/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
deleted file mode 100644
index 330c7f6..0000000
--- a/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
+++ /dev/null
@@ -1 +0,0 @@
-<beans/>
\ No newline at end of file

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

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

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

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


[3/4] tomee git commit: Some refactoring to remove Java 8 lambdas

Posted by jl...@apache.org.
Some refactoring to remove Java 8 lambdas


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

Branch: refs/heads/master
Commit: 72c0832184c4354627cb97a52f557e6d0ffb4aa2
Parents: 09ca434
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Apr 17 01:27:50 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Apr 17 01:27:50 2018 +0200

----------------------------------------------------------------------
 mp-jwt/pom.xml                                  |  93 +++++
 .../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 +++++++
 mp-jwt/src/main/resources/META-INF/beans.xml    |   1 +
 .../META-INF/org.apache.openejb.extension       |   1 +
 .../javax.enterprise.inject.spi.Extension       |   1 +
 .../javax.servlet.ServletContainerInitializer   |   1 +
 ...file.jwt.principal.JWTCallerPrincipalFactory |   1 +
 pom.xml                                         |   1 +
 tck/mp-jwt-embedded/pom.xml                     |  44 +--
 .../tomee/microprofile/jwt/MPJWTFilter.java     | 258 -------------
 .../microprofile/jwt/MPJWTInitializer.java      |  64 ----
 .../tomee/microprofile/jwt/ParseException.java  |  32 --
 .../tomee/microprofile/jwt/cdi/ClaimBean.java   | 360 ------------------
 .../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 | 100 -----
 .../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 -------
 .../src/main/resources/META-INF/beans.xml       |   1 -
 .../META-INF/org.apache.openejb.extension       |   1 -
 .../javax.enterprise.inject.spi.Extension       |   1 -
 .../javax.servlet.ServletContainerInitializer   |   1 -
 ...file.jwt.principal.JWTCallerPrincipalFactory |   1 -
 51 files changed, 2225 insertions(+), 2107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/mp-jwt/pom.xml
----------------------------------------------------------------------
diff --git a/mp-jwt/pom.xml b/mp-jwt/pom.xml
new file mode 100644
index 0000000..adc79c6
--- /dev/null
+++ b/mp-jwt/pom.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.
+  -->
+<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>7.0.5-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>${project.groupId}</groupId>
+      <artifactId>javaee-api</artifactId>
+    </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.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.bitbucket.b_c</groupId>
+      <artifactId>jose4j</artifactId>
+      <version>0.6.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.microprofile.jwt</groupId>
+      <artifactId>microprofile-jwt-auth-tck</artifactId>
+      <version>${mp-jwt.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jsonb_1.0_spec</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.johnzon</groupId>
+      <artifactId>johnzon-jsonb</artifactId>
+      <version>1.1.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-catalina</artifactId>
+      <version>${tomcat.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/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..17be756
--- /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.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/72c08321/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/72c08321/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/72c08321/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..59f42c5
--- /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.JsonbBuilder;
+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 JsonbBuilder.create();
+    }
+
+    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/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/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


[2/4] tomee git commit: Some refactoring to remove Java 8 lambdas

Posted by jl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/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/72c08321/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/72c08321/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/72c08321/mp-jwt/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/resources/META-INF/beans.xml b/mp-jwt/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..330c7f6
--- /dev/null
+++ b/mp-jwt/src/main/resources/META-INF/beans.xml
@@ -0,0 +1 @@
+<beans/>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/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/72c08321/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/72c08321/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/72c08321/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/72c08321/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 45f8d5a..3be6c9f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -508,6 +508,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/72c08321/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index 2af8f28..702e56e 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -34,19 +34,8 @@
   <dependencies>
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>javaee-api</artifactId>
-    </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>
+      <artifactId>mp-jwt</artifactId>
+      <version>${tomee.version}</version>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
@@ -97,33 +86,6 @@
       <version>${version.arquillian}</version>
     </dependency>
 
-    <dependency>
-      <groupId>org.bitbucket.b_c</groupId>
-      <artifactId>jose4j</artifactId>
-      <version>0.6.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-jsonb_1.0_spec</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.johnzon</groupId>
-      <artifactId>johnzon-jsonb</artifactId>
-      <version>1.1.2</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.tomcat</groupId>
-      <artifactId>tomcat-catalina</artifactId>
-      <version>${tomcat.version}</version>
-      <scope>provided</scope>
-    </dependency>
   </dependencies>
 
   <build>
@@ -134,7 +96,7 @@
         <version>3.6.1</version>
         <configuration>
           <source>1.8</source>
-          <target>1.8</target>JwSecTest
+          <target>1.8</target>
         </configuration>
       </plugin>
       <!--

http://git-wip-us.apache.org/repos/asf/tomee/blob/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
deleted file mode 100644
index 25bf828..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ /dev/null
@@ -1,258 +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;
-
-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>) () -> {
-                final Set<Principal> principals = new LinkedHashSet<>();
-                final JsonWebToken namePrincipal = tokenFunction.apply(request);
-                principals.add(namePrincipal);
-                principals.addAll(namePrincipal.getGroups().stream().map(role -> (Principal) () -> role).collect(Collectors.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
deleted file mode 100644
index cede7dc..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ /dev/null
@@ -1,64 +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;
-
-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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
deleted file mode 100644
index d9572d5..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
+++ /dev/null
@@ -1,32 +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;
-
-/**
- * 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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
deleted file mode 100644
index 6c7a00d..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ /dev/null
@@ -1,360 +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.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.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(() -> {
-                            final T claimValue = getClaimValue(key);
-                            return Optional.ofNullable(claimValue);
-                        });
-
-                    } else if (ParameterizedType.class.isInstance(claimValueType) && isSet(ParameterizedType.class.cast(claimValueType))) {
-                        claimValueWrapper.setValue(() -> {
-                            final T claimValue = getClaimValue(key);
-                            return claimValue;
-                        });
-
-                    } else if (ParameterizedType.class.isInstance(claimValueType) && isList(ParameterizedType.class.cast(claimValueType))) {
-                        claimValueWrapper.setValue(() -> {
-                            final T claimValue = getClaimValue(key);
-                            return claimValue;
-                        });
-
-                    } else if (Class.class.isInstance(claimValueType)) {
-                        claimValueWrapper.setValue(() -> {
-                            final T claimValue = 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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
deleted file mode 100644
index 17be756..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *     Licensed to the Apache Software Foundation (ASF) under one or more
- *     contributor license agreements.  See the NOTICE file distributed with
- *     this work for additional information regarding copyright ownership.
- *     The ASF licenses this file to You under the Apache License, Version 2.0
- *     (the "License"); you may not use this file except in compliance with
- *     the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *     Unless required by applicable law or agreed to in writing, software
- *     distributed under the License is distributed on an "AS IS" BASIS,
- *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *     See the License for the specific language governing permissions and
- *     limitations under the License.
- */
-package org.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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
deleted file mode 100644
index 2836abd..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
+++ /dev/null
@@ -1,53 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
deleted file mode 100644
index 273ff96..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
+++ /dev/null
@@ -1,24 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
deleted file mode 100644
index 59f42c5..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
+++ /dev/null
@@ -1,46 +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.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.JsonbBuilder;
-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 JsonbBuilder.create();
-    }
-
-    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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
deleted file mode 100644
index d1019ee..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ /dev/null
@@ -1,100 +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.cdi;
-
-import org.apache.tomee.microprofile.jwt.MPJWTFilter;
-import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
-import org.apache.tomee.microprofile.jwt.TCKTokenParser;
-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.Predicate;
-import java.util.stream.Collectors;
-
-public class MPJWTCDIExtension implements Extension {
-
-    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 {
-        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(ip -> REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType()))
-                .collect(Collectors.toSet());
-
-        final Set<Type> providerTypes = injectionPoints.stream()
-                .filter(NOT_PROVIDERS.negate())
-                .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
-                .collect(Collectors.toSet());
-
-        final Set<Type> instanceTypes = injectionPoints.stream()
-                .filter(NOT_INSTANCES.negate())
-                .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
-                .collect(Collectors.toSet());
-
-        types.addAll(providerTypes);
-        types.addAll(instanceTypes);
-
-        types.stream()
-                .map(type -> new ClaimBean<>(bm, type))
-                .forEach(abd::addBean);
-    }
-
-    public void observeBeforeBeanDiscovery(@Observes final BeforeBeanDiscovery bbd, final BeanManager beanManager) {
-        bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
-        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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
deleted file mode 100644
index 42034b9..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ /dev/null
@@ -1,49 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
deleted file mode 100644
index a969515..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
+++ /dev/null
@@ -1,67 +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 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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
deleted file mode 100644
index 9247e04..0000000
--- a/tck/mp-jwt-embedded/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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
deleted file mode 100644
index 34f152f..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
+++ /dev/null
@@ -1,36 +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.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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
deleted file mode 100644
index f604e6b..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-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/72c08321/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
deleted file mode 100644
index 58b3203..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
+++ /dev/null
@@ -1,144 +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.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


[4/4] tomee git commit: Fix java compilation issues

Posted by jl...@apache.org.
Fix java compilation issues


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

Branch: refs/heads/master
Commit: 387c11af07b3867f84c4aa65e76a8db89a4a5dc8
Parents: 72c0832
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Apr 17 01:52:04 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Apr 17 01:52:04 2018 +0200

----------------------------------------------------------------------
 .../apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java   | 2 +-
 .../org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/387c11af/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
index 17be756..2f1fd3d 100644
--- 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
@@ -50,7 +50,7 @@ public class ClaimInjectionPoint implements InjectionPoint {
 
     @Override
     public Set<Annotation> getQualifiers() {
-        return Collections.singleton(DefaultLiteral.INSTANCE);
+        return Collections.<Annotation>singleton(DefaultLiteral.INSTANCE);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tomee/blob/387c11af/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
index 59f42c5..53a9088 100644
--- 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
@@ -20,7 +20,7 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.inject.Disposes;
 import javax.enterprise.inject.Produces;
 import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import javax.json.bind.spi.JsonbProvider;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -32,7 +32,7 @@ public class JsonbProducer {
 
     @Produces
     public Jsonb create() {
-        return JsonbBuilder.create();
+        return JsonbProvider.provider().create().build();
     }
 
     public void close(@Disposes final Jsonb jsonb) {