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:18 UTC
[15/38] tomee git commit: TOMEE-2247 - Initial support for JWK.
TOMEE-2247 - Initial support for JWK.
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/e3aaa333
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/e3aaa333
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/e3aaa333
Branch: refs/heads/master
Commit: e3aaa333c7a6d98da3e07d9a23694c3d6c773711
Parents: 66c93e8
Author: Roberto Cortez <ra...@yahoo.com>
Authored: Tue Sep 25 11:00:19 2018 +0100
Committer: Roberto Cortez <ra...@yahoo.com>
Committed: Fri Dec 7 18:11:18 2018 +0000
----------------------------------------------------------------------
.../config/ConfigurableJWTAuthContextInfo.java | 63 +++++++++++++++++---
.../jwt/MicroProfileJWTTCKArchiveProcessor.java | 2 +
2 files changed, 57 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/e3aaa333/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
index 76d5a62..dd2e74f 100644
--- 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
@@ -17,18 +17,25 @@
package org.apache.tomee.microprofile.jwt.config;
import org.eclipse.microprofile.config.Config;
+import org.jose4j.jwk.JsonWebKey;
+import org.jose4j.lang.JoseException;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.DeploymentException;
import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.stream.JsonParsingException;
import javax.servlet.ServletContext;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.StringReader;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
@@ -91,7 +98,17 @@ public class ConfigurableJWTAuthContextInfo {
}
private RSAPublicKey readPublicKey(final String publicKey) {
- return parsePCKS8(publicKey);
+ final Stream<Supplier<Optional<RSAPublicKey>>> possiblePublicKeysParses =
+ Stream.of(() -> parsePCKS8(publicKey),
+ () -> parseJwk(publicKey),
+ () -> parseJwk(new String(Base64.getDecoder().decode(publicKey))));
+
+ return possiblePublicKeysParses
+ .map(Supplier::get)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst()
+ .orElseThrow(() -> new DeploymentException("Could not read MicroProfile Public Key: " + publicKey));
}
private RSAPublicKey readPublicKeyFromLocation(final String publicKeyLocation) {
@@ -178,24 +195,54 @@ public class ConfigurableJWTAuthContextInfo {
return content.toString();
}
- private RSAPublicKey parsePCKS8(final String publicKey) {
- isPrivatePCKS8(publicKey);
+ private Optional<RSAPublicKey> parsePCKS8(final String publicKey) {
try {
final X509EncodedKeySpec spec = new X509EncodedKeySpec(normalizeAndDecodePCKS8(publicKey));
final KeyFactory kf = KeyFactory.getInstance("RSA");
- return (RSAPublicKey) kf.generatePublic(spec);
+ return Optional.of((RSAPublicKey) kf.generatePublic(spec));
} catch (final NoSuchAlgorithmException | InvalidKeySpecException e) {
- throw new DeploymentException("Could not read MicroProfile Public Key: " + publicKey, 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 Optional<RSAPublicKey> parseJwk(final String publicKey) {
+ final JsonObject jwk;
+ try {
+ jwk = Json.createReader(new StringReader(publicKey)).readObject();
+ } catch (final JsonParsingException e) {
+ return Optional.empty();
+ }
+
+ final String keyType = jwk.getString("kty");
+ if (keyType == null) {
+ throw new DeploymentException("MicroProfile Public Key JWK kty field is missing.");
+ }
+
+ if ("RSA".equals(keyType)) {
+ try {
+ return Optional.of((RSAPublicKey) JsonWebKey.Factory.newJwk(publicKey).getKey());
+ } catch (final JoseException e) {
+ throw new DeploymentException("Could not read MicroProfile Public Key JWK.", e);
+ }
+ }
+
+ throw new DeploymentException("MicroProfile Public Key JWK kty not supported: " + keyType);
+ }
+
+ private Optional<JsonObject> readEncodedJwk(final String publicKey) {
+ try {
+ return Optional.of(
+ Json.createReader(new ByteArrayInputStream(Base64.getDecoder().decode(publicKey))).readObject());
+ } catch (final JsonParsingException e) {
+ return Optional.empty();
}
}
private byte[] normalizeAndDecodePCKS8(final String publicKey) {
+ if (publicKey.contains("PRIVATE KEY")) {
+ throw new DeploymentException("MicroProfile Public Key is Private.");
+ }
+
final String normalizedKey =
publicKey.replaceAll("-----BEGIN (.*)-----", "")
.replaceAll("-----END (.*)----", "")
http://git-wip-us.apache.org/repos/asf/tomee/blob/e3aaa333/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/MicroProfileJWTTCKArchiveProcessor.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/MicroProfileJWTTCKArchiveProcessor.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/MicroProfileJWTTCKArchiveProcessor.java
index bd4d8f3..ab98f42 100644
--- a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/MicroProfileJWTTCKArchiveProcessor.java
+++ b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/MicroProfileJWTTCKArchiveProcessor.java
@@ -21,6 +21,7 @@ import org.apache.openejb.loader.JarLocation;
import org.apache.tomee.arquillian.remote.RemoteTomEEConfiguration;
import org.apache.tomee.arquillian.remote.RemoteTomEEContainer;
import org.eclipse.microprofile.jwt.tck.config.IssValidationTest;
+import org.eclipse.microprofile.jwt.tck.config.PublicKeyAsBase64JWKTest;
import org.eclipse.microprofile.jwt.tck.config.PublicKeyAsFileLocationURLTest;
import org.eclipse.microprofile.jwt.tck.config.PublicKeyAsPEMLocationTest;
import org.eclipse.microprofile.jwt.tck.config.PublicKeyAsPEMTest;
@@ -70,6 +71,7 @@ public class MicroProfileJWTTCKArchiveProcessor implements ApplicationArchivePro
PublicKeyAsPEMTest.class,
PublicKeyAsPEMLocationTest.class,
PublicKeyAsFileLocationURLTest.class,
+ PublicKeyAsBase64JWKTest.class,
IssValidationTest.class,
org.apache.tomee.microprofile.tck.jwt.config.PublicKeyAsPEMLocationTest.class)
.filter(c -> c.equals(testClass.getJavaClass()))