some refactoring
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1ad96bbd Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1ad96bbd Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1ad96bbd Branch: refs/heads/master Commit: 1ad96bbdf1239c4d57cb5b0bc9fa857fa028f427 Parents: 812cfed Author: Jean-Louis Monteiro <jeano...@gmail.com> Authored: Tue Feb 27 11:03:11 2018 +0100 Committer: Jean-Louis Monteiro <jeano...@gmail.com> Committed: Tue Feb 27 11:03:11 2018 +0100 ---------------------------------------------------------------------- tck/mp-jwt-embedded/pom.xml | 16 ++-- .../apache/tomee/microprofile/jwt/KeyUtils.java | 85 ------------------- .../tomee/microprofile/jwt/MPJWTFilter.java | 2 +- .../microprofile/jwt/MPJWTInitializer.java | 1 + .../tomee/microprofile/jwt/ParseException.java | 4 +- .../tomee/microprofile/jwt/TCKTokenParser.java | 2 +- .../microprofile/jwt/cdi/ClaimLiteral.java | 32 -------- .../jwt/cdi/ClaimProviderBeanAttributes.java | 23 ++---- .../jwt/cdi/ClaimValueProducer.java | 16 ++-- .../microprofile/jwt/cdi/ClaimValueWrapper.java | 13 ++- .../microprofile/jwt/cdi/JsonValueProducer.java | 37 ++++----- .../microprofile/jwt/cdi/JsonbProducer.java | 45 ++++++++++ .../microprofile/jwt/cdi/MPJWTCDIExtension.java | 15 +--- .../microprofile/jwt/cdi/MPJWTProducer.java | 86 +++----------------- .../jwt/cdi/RawClaimTypeProducer.java | 21 ++--- .../jwt/config/JWTAuthContextInfoProvider.java | 42 +++++----- .../principal/DefaultJWTCallerPrincipal.java | 6 +- tck/mp-jwt-embedded/src/test/resources/dev.xml | 6 +- 18 files changed, 148 insertions(+), 304 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/pom.xml ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml index 272f4ad..5055ac4 100644 --- a/tck/mp-jwt-embedded/pom.xml +++ b/tck/mp-jwt-embedded/pom.xml @@ -96,15 +96,21 @@ <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>javax.json.bind</groupId> - <artifactId>javax.json.bind-api</artifactId> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-jsonb_1.0_spec</artifactId> <version>1.0</version> </dependency> <dependency> - <groupId>org.glassfish</groupId> - <artifactId>javax.json</artifactId> - <version>1.0.4</version> + <groupId>org.apache.johnzon</groupId> + <artifactId>johnzon-jsonb</artifactId> + <version>1.1.2</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java deleted file mode 100644 index c65ea98..0000000 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java +++ /dev/null @@ -1,85 +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 java.io.InputStream; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; - -public class KeyUtils { - private KeyUtils() { - } - - public static PrivateKey readPrivateKey(String pemResName) throws Exception { - InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName); - byte[] tmp = new byte[4096]; - int length = contentIS.read(tmp); - PrivateKey privateKey = decodePrivateKey(new String(tmp, 0, length)); - return privateKey; - } - - public static PublicKey readPublicKey(String pemResName) throws Exception { - InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName); - byte[] tmp = new byte[4096]; - int length = contentIS.read(tmp); - PublicKey publicKey = decodePublicKey(new String(tmp, 0, length)); - return publicKey; - } - - public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); - keyPairGenerator.initialize(keySize); - KeyPair keyPair = keyPairGenerator.genKeyPair(); - return keyPair; - } - - public static PrivateKey decodePrivateKey(String pemEncoded) throws Exception { - pemEncoded = removeBeginEnd(pemEncoded); - byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(pemEncoded); - - // extract the private key - - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - PrivateKey privKey = kf.generatePrivate(keySpec); - return privKey; - } - - public static PublicKey decodePublicKey(String pemEncoded) throws Exception { - pemEncoded = removeBeginEnd(pemEncoded); - byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded); - - X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePublic(spec); - } - - private static String removeBeginEnd(String pem) { - pem = pem.replaceAll("-----BEGIN(.*)KEY-----", ""); - pem = pem.replaceAll("-----END(.*)KEY-----", ""); - pem = pem.replaceAll("\r\n", ""); - pem = pem.replaceAll("\n", ""); - return pem.trim(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 0c80696..752bcda 100644 --- 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 @@ -69,7 +69,7 @@ public class MPJWTFilter implements Filter { final String token = authorizationHeader.substring("bearer ".length()); final JsonWebToken jsonWebToken; try { - jsonWebToken = DefaultJWTCallerPrincipalFactory.instance().parse(token, authContextInfo); + jsonWebToken = validate(token); } catch (final ParseException e) { // todo properly handle the exception as required per spec http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 8fa9259..28a1735 100644 --- 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 @@ -60,6 +60,7 @@ public class MPJWTInitializer implements ServletContainerInitializer { MPJWTContext.addMapping( new MPJWTContext.MPJWTConfigKey( ctx.getContextPath(), + // todo instead of empty path, we need to look for default value applicationPath == null ? "" : applicationPath.value()), new MPJWTContext.MPJWTConfigValue( http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 60269b0..d9572d5 100644 --- 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 @@ -22,11 +22,11 @@ package org.apache.tomee.microprofile.jwt; public class ParseException extends Exception { private static final long serialVersionUID = 1L; - public ParseException(String message) { + public ParseException(final String message) { super(message); } - public ParseException(String message, Throwable cause) { + 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/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java index aeea598..ae563ec 100644 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java @@ -31,7 +31,7 @@ import java.security.interfaces.RSAPublicKey; public class TCKTokenParser implements ITokenParser { @Override - public JsonWebToken parse(String bearerToken, String issuer, PublicKey publicKey) throws Exception { + public JsonWebToken parse(final String bearerToken, final String issuer, final PublicKey publicKey) throws Exception { final JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer); final JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance(); return factory.parse(bearerToken, authContextInfo); http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java deleted file mode 100644 index 319f122..0000000 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.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.cdi; - -import org.eclipse.microprofile.jwt.Claim; -import org.eclipse.microprofile.jwt.Claims; - -import javax.enterprise.util.AnnotationLiteral; - -public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim { - public String value() { - return ""; - } - - public Claims standard() { - return Claims.UNKNOWN; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java index 88e7724..f15a3fe 100644 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java @@ -21,29 +21,16 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; -/** - * An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes - * to allow the MPJWTExtension to collect the types of all corresponding injection sites - */ public class ClaimProviderBeanAttributes implements BeanAttributes<Object> { - private BeanAttributes<Object> delegate; - private Set<Type> types; - private Set<Annotation> qualifiers; - /** - * Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected - * from all injection points annotated with @ConfigProperty. - * - * @param delegate - the original producer method BeanAttributes - * @param types - the full set of @Claim injection point types - */ - public ClaimProviderBeanAttributes(BeanAttributes<Object> delegate, Set<Type> types, Set<Annotation> qualifiers) { + private final BeanAttributes<Object> delegate; + private final Set<Type> types; + private final Set<Annotation> qualifiers; + + public ClaimProviderBeanAttributes(final BeanAttributes<Object> delegate, final Set<Type> types, final Set<Annotation> qualifiers) { this.delegate = delegate; this.types = types; this.qualifiers = qualifiers; - if (types.size() == 0) { - Thread.dumpStack(); - } } @Override http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java index 1881401..aeed7c8 100644 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java @@ -22,25 +22,25 @@ import org.eclipse.microprofile.jwt.Claims; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Inject; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Optional; -/** - * A producer for the ClaimValue<T> wrapper injection sites. - * - * @param <T> the raw claim type - */ public class ClaimValueProducer<T> { + @Inject + private MPJWTProducer producer; + @Produces @Claim("") - ClaimValue<T> produce(InjectionPoint ip) { + ClaimValue<T> produce(final InjectionPoint ip) { String name = getName(ip); - ClaimValue<Optional<T>> cv = MPJWTProducer.generalClaimValueProducer(name); + ClaimValue<Optional<T>> cv = producer.generalClaimValueProducer(name); ClaimValue<T> returnValue = (ClaimValue<T>) cv; Optional<T> value = cv.getValue(); + // Pull out the ClaimValue<T> T type, Type matchType = ip.getType(); Type actualType = Object.class; @@ -62,7 +62,7 @@ public class ClaimValueProducer<T> { return returnValue; } - String getName(InjectionPoint ip) { + String getName(final InjectionPoint ip) { String name = null; for (Annotation ann : ip.getQualifiers()) { if (ann instanceof Claim) { http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 6776191..e0aa68f 100644 --- 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 @@ -18,14 +18,9 @@ package org.apache.tomee.microprofile.jwt.cdi; import org.eclipse.microprofile.jwt.ClaimValue; -/** - * An implementation of the ClaimValue interface - * - * @param <T> the claim value type - */ public class ClaimValueWrapper<T> implements ClaimValue<T> { - private String name; + private final String name; private T value; public ClaimValueWrapper(String name) { @@ -48,7 +43,9 @@ public class ClaimValueWrapper<T> implements ClaimValue<T> { @Override public String toString() { - return String.format("ClaimValueWrapper[@%s], name=%s, value[%s]=%s", Integer.toHexString(hashCode()), - name, value.getClass(), value); + return "ClaimValueWrapper{" + + "name='" + name + '\'' + + ", value=" + value + + '}'; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java index 2f991b2..af15b89 100644 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java @@ -21,6 +21,7 @@ import org.eclipse.microprofile.jwt.Claims; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Inject; import javax.json.JsonArray; import javax.json.JsonNumber; import javax.json.JsonObject; @@ -28,77 +29,73 @@ import javax.json.JsonString; import javax.json.JsonValue; import java.lang.annotation.Annotation; import java.util.Optional; -import java.util.logging.Logger; -/** - * A producer for JsonValue injection types - */ public class JsonValueProducer { - private static Logger log = Logger.getLogger(JsonValueProducer.class.getName()); + + @Inject + private MPJWTProducer producer; @Produces @Claim("") - public JsonString getJsonString(InjectionPoint ip) { + public JsonString getJsonString(final InjectionPoint ip) { return getValue(ip); } @Produces @Claim("") - public Optional<JsonString> getOptionalJsonString(InjectionPoint ip) { + public Optional<JsonString> getOptionalJsonString(final InjectionPoint ip) { return getOptionalValue(ip); } @Produces @Claim("") - public JsonNumber getJsonNumber(InjectionPoint ip) { + public JsonNumber getJsonNumber(final InjectionPoint ip) { return getValue(ip); } @Produces @Claim("") - public Optional<JsonNumber> getOptionalJsonNumber(InjectionPoint ip) { + public Optional<JsonNumber> getOptionalJsonNumber(final InjectionPoint ip) { return getOptionalValue(ip); } @Produces @Claim("") - public JsonArray getJsonArray(InjectionPoint ip) { + public JsonArray getJsonArray(final InjectionPoint ip) { return getValue(ip); } @Produces @Claim("") - public Optional<JsonArray> getOptionalJsonArray(InjectionPoint ip) { + public Optional<JsonArray> getOptionalJsonArray(final InjectionPoint ip) { return getOptionalValue(ip); } @Produces @Claim("") - public JsonObject getJsonObject(InjectionPoint ip) { + public JsonObject getJsonObject(final InjectionPoint ip) { return getValue(ip); } @Produces @Claim("") - public Optional<JsonObject> getOptionalJsonObject(InjectionPoint ip) { + public Optional<JsonObject> getOptionalJsonObject(final InjectionPoint ip) { return getOptionalValue(ip); } - public <T extends JsonValue> T getValue(InjectionPoint ip) { - log.fine(String.format("JsonValueProducer(%s).produce", ip)); + public <T extends JsonValue> T getValue(final InjectionPoint ip) { String name = getName(ip); - T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name); + T jsonValue = (T) producer.generalJsonValueProducer(name); return jsonValue; } - public <T extends JsonValue> Optional<T> getOptionalValue(InjectionPoint ip) { - log.fine(String.format("JsonValueProducer(%s).produce", ip)); + public <T extends JsonValue> Optional<T> getOptionalValue(final InjectionPoint ip) { String name = getName(ip); - T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name); + T jsonValue = (T) producer.generalJsonValueProducer(name); return Optional.ofNullable(jsonValue); } - String getName(InjectionPoint ip) { + String getName(final InjectionPoint ip) { String name = null; for (Annotation ann : ip.getQualifiers()) { if (ann instanceof Claim) { http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 new file mode 100644 index 0000000..7774cbf --- /dev/null +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 +public class JsonbProducer { + + private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName()); + + @Produces + public Jsonb jsonb() { + 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/1ad96bbd/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 index 3700494..7375d65 100644 --- 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 @@ -48,20 +48,6 @@ import java.util.Optional; import java.util.Set; import java.util.logging.Logger; -/** - * A CDI extension that provides a producer for the current authenticated JsonWebToken based on a thread - * local value that is managed by the {@link JWTAuthMechanism} request - * authentication handler. - * <p> - * This also installs the producer methods for the discovered: - * <ul> - * <li>@Claim ClaimValue<T> injection sites.</li> - * <li>@Claim raw type<T> injection sites.</li> - * <li>@Claim JsonValue injection sites.</li> - * </ul> - * - * @see JWTAuthMechanism - */ public class MPJWTCDIExtension implements Extension { private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName()); /** @@ -83,6 +69,7 @@ public class MPJWTCDIExtension implements Extension { public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) { log.fine("MPJWTExtension(), added JWTPrincipalProducer"); 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)); http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 42cc8ac..16876fb 100644 --- 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 @@ -19,33 +19,26 @@ package org.apache.tomee.microprofile.jwt.cdi; import org.eclipse.microprofile.jwt.ClaimValue; import org.eclipse.microprofile.jwt.JsonWebToken; -import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.context.Destroyed; -import javax.enterprise.context.Initialized; import javax.enterprise.context.RequestScoped; -import javax.enterprise.event.Observes; import javax.enterprise.inject.Produces; +import javax.inject.Inject; import javax.json.Json; -import javax.json.JsonArray; import javax.json.JsonArrayBuilder; import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; import javax.json.JsonValue; +import javax.json.bind.Jsonb; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.logging.Logger; -/** - * A class that tracks the current validated MP-JWT and associated JsonWebToken via a thread - * local to provide a @RequestScoped JsonWebToken producer method. - * <p> - * It also provides utility methods for access the current JsonWebToken claim values. - */ @ApplicationScoped public class MPJWTProducer { + + @Inject + private Jsonb jsonb; + private static final String TMP = "tmp"; private static Logger log = Logger.getLogger(MPJWTProducer.class.getName()); private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>(); @@ -58,14 +51,7 @@ public class MPJWTProducer { return currentPrincipal.get(); } - /** - * A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object. - * - * @param name - name of the claim - * @param <T> expected actual type of the claim - * @return the claim value wrapper object - */ - static <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) { + <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) { ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name); T value = getValue(name, false); Optional<T> optValue = Optional.ofNullable(value); @@ -73,19 +59,13 @@ public class MPJWTProducer { return wrapper; } - /** - * Return the indicated claim value as a JsonValue - * - * @param name - name of the claim - * @return a JsonValue wrapper - */ - static JsonValue generalJsonValueProducer(String name) { + JsonValue generalJsonValueProducer(String name) { Object value = getValue(name, false); JsonValue jsonValue = wrapValue(value); return jsonValue; } - public static <T> T getValue(String name, boolean isOptional) { + public <T> T getValue(String name, boolean isOptional) { JsonWebToken jwt = getJWTPrincpal(); if (jwt == null) { log.fine(String.format("getValue(%s), null JsonWebToken", name)); @@ -100,33 +80,11 @@ public class MPJWTProducer { return claimValue.orElse(null); } - static JsonObject replaceMap(Map<String, Object> map) { - JsonObjectBuilder builder = Json.createObjectBuilder(); - for (Map.Entry<String, Object> entry : map.entrySet()) { - Object entryValue = entry.getValue(); - if (entryValue instanceof Map) { - JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue); - builder.add(entry.getKey(), entryJsonObject); - } else if (entryValue instanceof List) { - JsonArray array = (JsonArray) wrapValue(entryValue); - builder.add(entry.getKey(), array); - } else if (entryValue instanceof Long || entryValue instanceof Integer) { - long lvalue = ((Number) entryValue).longValue(); - builder.add(entry.getKey(), lvalue); - } else if (entryValue instanceof Double || entryValue instanceof Float) { - double dvalue = ((Number) entryValue).doubleValue(); - builder.add(entry.getKey(), dvalue); - } else if (entryValue instanceof Boolean) { - boolean flag = ((Boolean) entryValue).booleanValue(); - builder.add(entry.getKey(), flag); - } else if (entryValue instanceof String) { - builder.add(entry.getKey(), entryValue.toString()); - } - } - return builder.build(); + JsonObject replaceMap(final Map<String, Object> map) { + return jsonb.fromJson(jsonb.toJson(map), JsonObject.class); } - static JsonValue wrapValue(Object value) { + JsonValue wrapValue(Object value) { JsonValue jsonValue = null; if (value instanceof JsonValue) { // This may already be a JsonValue @@ -170,27 +128,9 @@ public class MPJWTProducer { return jsonValue; } - @PostConstruct - void init() { - log.fine("MPJWTProducer initialized"); - } - - void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) { - log.finest(String.format("observeRequestInitialized, event=%s", event)); - } - - void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) { - log.finest(String.format("observeRequestDestroyed, event=%s", event)); - } - - /** - * The @RequestScoped producer method for the current JsonWebToken - * - * @return - */ @Produces @RequestScoped - JsonWebToken currentPrincipalOrNull() { + JsonWebToken currentPrincipal() { return currentPrincipal.get(); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java index 1ab817e..55b6324 100644 --- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java +++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java @@ -22,24 +22,22 @@ import org.eclipse.microprofile.jwt.Claims; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Inject; import javax.inject.Named; import java.lang.annotation.Annotation; import java.util.Optional; -import java.util.logging.Logger; -/** - * - */ public class RawClaimTypeProducer { - private static Logger log = Logger.getLogger(RawClaimTypeProducer.class.getName()); + + @Inject + private MPJWTProducer producer; @Produces @Claim("") @Named("RawClaimTypeProducer#getValue") - public Object getValue(InjectionPoint ip) { - log.fine(String.format("getValue(%s)", ip)); + public Object getValue(final InjectionPoint ip) { String name = getName(ip); - ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name); + ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name); Optional<Object> value = cv.getValue(); Object returnValue = value.orElse(null); return returnValue; @@ -48,15 +46,14 @@ public class RawClaimTypeProducer { @Produces @Claim("") @Named("RawClaimTypeProducer#getOptionalValue") - public Optional getOptionalValue(InjectionPoint ip) { - log.fine(String.format("getOptionalValue(%s)", ip)); + public Optional getOptionalValue(final InjectionPoint ip) { String name = getName(ip); - ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name); + ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name); Optional<Object> value = cv.getValue(); return value; } - String getName(InjectionPoint ip) { + String getName(final InjectionPoint ip) { String name = null; for (Annotation ann : ip.getQualifiers()) { if (ann instanceof Claim) { http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index b810fcf..9247e04 100644 --- 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 @@ -16,46 +16,46 @@ */ package org.apache.tomee.microprofile.jwt.config; -import org.apache.tomee.microprofile.jwt.KeyUtils; - 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() { + Optional<JWTAuthContextInfo> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException { JWTAuthContextInfo contextInfo = new JWTAuthContextInfo(); // todo use MP Config to load the configuration contextInfo.setIssuedBy("https://server.example.com"); - RSAPublicKey pk = null; - try { - pk = (RSAPublicKey) KeyUtils.decodePublicKey("-----BEGIN RSA PUBLIC KEY-----\n" + - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq\n" + - "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR\n" + - "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e\n" + - "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9\n" + - "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn\n" + - "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x\n" + - "nQIDAQAB\n" + - "-----END RSA PUBLIC KEY-----\n"); - - } catch (final Exception e) { - e.printStackTrace(); - // todo better handling - throw new RuntimeException(e); - } + + 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() { + JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException { return getOptionalContextInfo().get(); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/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 index 120058d..47c6ad3 100644 --- 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 @@ -53,7 +53,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal { * @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(String jwt, String type, JwtClaims claimsSet, String name) { + public DefaultJWTCallerPrincipal(final String jwt, final String type, final JwtClaims claimsSet, final String name) { super(name); this.jwt = jwt; this.type = type; @@ -100,7 +100,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal { } @Override - public Object getClaim(String claimName) { + public Object getClaim(final String claimName) { Claims claimType = Claims.UNKNOWN; Object claim = null; try { @@ -138,7 +138,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal { } @Override - public boolean implies(Subject subject) { + public boolean implies(final Subject subject) { return false; } http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/test/resources/dev.xml ---------------------------------------------------------------------- diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml index f6c4fbd..88932f9 100644 --- a/tck/mp-jwt-embedded/src/test/resources/dev.xml +++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml @@ -76,9 +76,13 @@ </run> </groups> <classes> + <!-- OK + --> <class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" /> - <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" /> <class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" /> + <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" /> + <!-- KO + --> </classes> </test>