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/12/10 14:47:05 UTC
[02/38] tomee git commit: TOMEE-2247 - Added support for MP
Configuration.
TOMEE-2247 - Added support for MP Configuration.
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/458da041
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/458da041
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/458da041
Branch: refs/heads/master
Commit: 458da0419c8225a7a4b6af9da03921b3ef388b9d
Parents: 3b717d9
Author: Roberto Cortez <ra...@yahoo.com>
Authored: Wed Sep 12 12:30:48 2018 +0100
Committer: Roberto Cortez <ra...@yahoo.com>
Committed: Fri Dec 7 18:08:35 2018 +0000
----------------------------------------------------------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 22 ++++--
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 2 +
.../config/ConfigurableJWTAuthContextInfo.java | 78 ++++++++++++++++++++
.../jwt/AppDeploymentExtension.java | 18 ++++-
4 files changed, 113 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/458da041/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
index 78f059e..ee3be1b 100644
--- 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
@@ -16,6 +16,7 @@
*/
package org.apache.tomee.microprofile.jwt;
+import org.apache.tomee.microprofile.jwt.config.ConfigurableJWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
import org.eclipse.microprofile.jwt.JsonWebToken;
@@ -41,6 +42,7 @@ import java.security.Principal;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Locale;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Function;
@@ -49,10 +51,6 @@ 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 Instance<JWTAuthContextInfo> authContextInfo;
-
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
// nothing so far
@@ -60,7 +58,8 @@ public class MPJWTFilter implements Filter {
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
- if (authContextInfo.isUnsatisfied()) {
+ final Optional<JWTAuthContextInfo> authContextInfo = getAuthContextInfo();
+ if (!authContextInfo.isPresent()) {
chain.doFilter(request,response);
return;
}
@@ -91,6 +90,19 @@ public class MPJWTFilter implements Filter {
// nothing to do
}
+ @Inject
+ private Instance<JWTAuthContextInfo> authContextInfo;
+ @Inject
+ private ConfigurableJWTAuthContextInfo configurableJWTAuthContextInfo;
+
+ private Optional<JWTAuthContextInfo> getAuthContextInfo() {
+ if (!authContextInfo.isUnsatisfied()) {
+ return Optional.of(authContextInfo.get());
+ }
+
+ return configurableJWTAuthContextInfo.getJWTAuthContextInfo();
+ }
+
private static Function<HttpServletRequest, JsonWebToken> token(final HttpServletRequest httpServletRequest, final JWTAuthContextInfo authContextInfo) {
return new Function<HttpServletRequest, JsonWebToken>() {
http://git-wip-us.apache.org/repos/asf/tomee/blob/458da041/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index f93fab4..0d7b95a 100644
--- a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -19,6 +19,7 @@ package org.apache.tomee.microprofile.jwt.cdi;
import org.apache.openejb.loader.SystemInstance;
import org.apache.tomee.microprofile.jwt.MPJWTFilter;
import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
+import org.apache.tomee.microprofile.jwt.config.ConfigurableJWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.jaxrs.MPJWPProviderRegistration;
import org.eclipse.microprofile.jwt.Claim;
@@ -96,6 +97,7 @@ public class MPJWTCDIExtension implements Extension {
}
public void observeBeforeBeanDiscovery(@Observes final BeforeBeanDiscovery bbd, final BeanManager beanManager) {
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(ConfigurableJWTAuthContextInfo.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
http://git-wip-us.apache.org/repos/asf/tomee/blob/458da041/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/ConfigurableJWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/ConfigurableJWTAuthContextInfo.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/ConfigurableJWTAuthContextInfo.java
new file mode 100644
index 0000000..59af1d6
--- /dev/null
+++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/ConfigurableJWTAuthContextInfo.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.jwt.config.Names;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.inject.Inject;
+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;
+
+@RequestScoped
+public class ConfigurableJWTAuthContextInfo {
+ @Inject
+ private Config config;
+
+ public Optional<JWTAuthContextInfo> getJWTAuthContextInfo() {
+ final Optional<String> publicKey = config.getOptionalValue(Names.VERIFIER_PUBLIC_KEY, String.class);
+ final Optional<String> issuer = config.getOptionalValue(Names.ISSUER, String.class);
+
+ if (publicKey.isPresent()) {
+ final Optional<RSAPublicKey> rsaPublicKey = parsePCKS8(publicKey.get());
+ if (rsaPublicKey.isPresent()) {
+ return Optional.of(new JWTAuthContextInfo(rsaPublicKey.get(), issuer.orElse("")));
+ }
+ }
+
+ return Optional.empty();
+ }
+
+ private Optional<RSAPublicKey> parsePCKS8(final String publicKey) {
+ isPrivatePCKS8(publicKey);
+ try {
+ final X509EncodedKeySpec spec = new X509EncodedKeySpec(normalizeAndDecodePCKS8(publicKey));
+ final KeyFactory kf = KeyFactory.getInstance("RSA");
+ return Optional.of((RSAPublicKey) kf.generatePublic(spec));
+ } catch (final NoSuchAlgorithmException | InvalidKeySpecException e) {
+ return Optional.empty();
+ }
+ }
+
+ private void isPrivatePCKS8(final String publicKey) {
+ if (publicKey.contains("PRIVATE KEY")) {
+ throw new DeploymentException("MicroProfile JWT Public Key is Private.");
+ }
+ }
+
+ private byte[] normalizeAndDecodePCKS8(final String publicKey) {
+ final String normalizedKey =
+ publicKey.replaceAll("-----BEGIN (.*)-----", "")
+ .replaceAll("-----END (.*)----", "")
+ .replaceAll("\r\n", "")
+ .replaceAll("\n", "");
+
+ return Base64.getDecoder().decode(normalizedKey);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/458da041/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
index f5f2183..8b9df7f 100644
--- a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
+++ b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
@@ -3,6 +3,7 @@ package org.apache.tomee.microprofile.jwt;
import com.nimbusds.jose.JWSSigner;
import org.apache.openejb.loader.JarLocation;
import org.eclipse.microprofile.jwt.tck.TCKConstants;
+import org.eclipse.microprofile.jwt.tck.config.PublicKeyAsPEMTest;
import org.eclipse.microprofile.jwt.tck.util.TokenUtils;
import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription;
import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
@@ -11,14 +12,15 @@ import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScena
import org.jboss.arquillian.core.spi.LoadableExtension;
import org.jboss.arquillian.test.spi.TestClass;
import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
-import java.net.URL;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.logging.Logger;
public class AppDeploymentExtension implements LoadableExtension {
@@ -71,7 +73,19 @@ public class AppDeploymentExtension implements LoadableExtension {
final WebArchive war = WebArchive.class.cast(appArchive);
war.addClass(JWTAuthContextInfoProvider.class);
+ // MP Config in wrong place - See https://github.com/eclipse/microprofile/issues/46.
+ final Map<ArchivePath, Node> content =
+ war.getContent(
+ object -> object.get().matches(".*META-INF/.*"));
+ content.forEach((archivePath, node) -> war.addAsResource(node.getAsset(), node.getPath()));
+
+ // Spec says that vendor specific ways to load the keys take precedence, so we need to remove it in test
+ // cases that use the Config approach.
+ if (testClass.getJavaClass().equals(PublicKeyAsPEMTest.class)) {
+ war.deleteClass(JWTAuthContextInfoProvider.class);
+ }
+
log.info("Augmented war: \n"+war.toString(true));
}
}
-}
\ No newline at end of file
+}