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:20 UTC
[17/38] tomee git commit: TOMEE-2247 - Refactor to support multiple
keys.
TOMEE-2247 - Refactor to support multiple keys.
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/be942d50
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/be942d50
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/be942d50
Branch: refs/heads/master
Commit: be942d5012a432d2be92e27cc272469bddbb679c
Parents: 46934a0
Author: Roberto Cortez <ra...@yahoo.com>
Authored: Tue Sep 25 19:00:47 2018 +0100
Committer: Roberto Cortez <ra...@yahoo.com>
Committed: Fri Dec 7 18:11:18 2018 +0000
----------------------------------------------------------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 1 -
.../config/ConfigurableJWTAuthContextInfo.java | 55 ++++++++++----------
.../jwt/config/JWTAuthContextInfo.java | 43 +++++++--------
.../DefaultJWTCallerPrincipalFactory.java | 4 +-
.../tck/jwt/JWTAuthContextInfoProvider.java | 9 +---
.../microprofile/tck/jwt/TCKTokenParser.java | 40 --------------
...lipse.microprofile.jwt.tck.util.ITokenParser | 1 -
7 files changed, 51 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/be942d50/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 9633819..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,7 +16,6 @@
*/
package org.apache.tomee.microprofile.jwt;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.tomee.microprofile.jwt.config.ConfigurableJWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
http://git-wip-us.apache.org/repos/asf/tomee/blob/be942d50/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 3705448..d5e302e 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
@@ -41,6 +41,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
+import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
@@ -48,6 +49,7 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
@@ -91,51 +93,50 @@ public class ConfigurableJWTAuthContextInfo {
}
private JWTAuthContextInfo createJWTAuthContextInfo() {
- final Stream<Supplier<Optional<RSAPublicKey>>> possiblePublicKeys =
- Stream.of(() -> getVerifierPublicKey().map(this::readPublicKey),
- () -> getPublicKeyLocation().map(this::readPublicKeyFromLocation));
+ final Stream<Supplier<Optional<List<Key>>>> possiblePublicKeys =
+ Stream.of(() -> getVerifierPublicKey().map(this::readPublicKeys),
+ () -> getPublicKeyLocation().map(this::readPublicKeysFromLocation));
return possiblePublicKeys
.map(Supplier::get)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
- .map(key -> new JWTAuthContextInfo(key, getIssuer().orElse(null)))
+ .map(keys -> JWTAuthContextInfo.authContextInfo(keys, getIssuer().orElse(null)))
.orElse(null);
}
- private RSAPublicKey readPublicKey(final String publicKey) {
- final Stream<Supplier<Optional<RSAPublicKey>>> possiblePublicKeysParses =
+ private List<Key> readPublicKeys(final String publicKey) {
+ final Stream<Supplier<List<Key>>> 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)
+ .filter(keys -> !keys.isEmpty())
.findFirst()
.orElseThrow(() -> new DeploymentException("Could not read MicroProfile Public Key: " + publicKey));
}
- private RSAPublicKey readPublicKeyFromLocation(final String publicKeyLocation) {
+ private List<Key> readPublicKeysFromLocation(final String publicKeyLocation) {
final Stream<Supplier<Optional<String>>> possiblePublicKeysLocations =
- Stream.of(() -> readPublicKeyFromClasspath(publicKeyLocation),
- () -> readPublicKeyFromFile(publicKeyLocation),
- () -> readPublicKeyFromHttp(publicKeyLocation),
- () -> readPublicKeyFromUrl(publicKeyLocation));
+ Stream.of(() -> readPublicKeysFromClasspath(publicKeyLocation),
+ () -> readPublicKeysFromFile(publicKeyLocation),
+ () -> readPublicKeysFromHttp(publicKeyLocation),
+ () -> readPublicKeysFromUrl(publicKeyLocation));
return possiblePublicKeysLocations
.map(Supplier::get)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
- .map(this::readPublicKey)
+ .map(this::readPublicKeys)
.orElseThrow(() -> new DeploymentException("Could not read MicroProfile Public Key from Location: " +
publicKeyLocation));
}
- private Optional<String> readPublicKeyFromClasspath(final String publicKeyLocation) {
+ private Optional<String> readPublicKeysFromClasspath(final String publicKeyLocation) {
try {
final InputStream is =
Thread.currentThread().getContextClassLoader().getResourceAsStream(publicKeyLocation);
@@ -149,7 +150,7 @@ public class ConfigurableJWTAuthContextInfo {
}
}
- private Optional<String> readPublicKeyFromFile(final String publicKeyLocation) {
+ private Optional<String> readPublicKeysFromFile(final String publicKeyLocation) {
if (!publicKeyLocation.startsWith("file")) {
return Optional.empty();
}
@@ -171,7 +172,7 @@ public class ConfigurableJWTAuthContextInfo {
}
}
- private Optional<String> readPublicKeyFromHttp(final String publicKeyLocation) {
+ private Optional<String> readPublicKeysFromHttp(final String publicKeyLocation) {
if (!publicKeyLocation.startsWith("http")) {
return Optional.empty();
}
@@ -185,7 +186,7 @@ public class ConfigurableJWTAuthContextInfo {
}
}
- private Optional<String> readPublicKeyFromUrl(final String publicKeyLocation) {
+ private Optional<String> readPublicKeysFromUrl(final String publicKeyLocation) {
try {
final URL locationURL = new URL(publicKeyLocation);
return Optional.of(readPublicKeyFromInputStream(locationURL.openStream()));
@@ -208,39 +209,39 @@ public class ConfigurableJWTAuthContextInfo {
return content.toString();
}
- private Optional<RSAPublicKey> parsePCKS8(final String publicKey) {
+ private List<Key> parsePCKS8(final String publicKey) {
try {
final X509EncodedKeySpec spec = new X509EncodedKeySpec(normalizeAndDecodePCKS8(publicKey));
final KeyFactory kf = KeyFactory.getInstance("RSA");
- return Optional.of((RSAPublicKey) kf.generatePublic(spec));
+ return Collections.singletonList(kf.generatePublic(spec));
} catch (final NoSuchAlgorithmException | InvalidKeySpecException | IllegalArgumentException e) {
- return Optional.empty();
+ return Collections.emptyList();
}
}
- private Optional<RSAPublicKey> parseJwk(final String publicKey) {
+ private List<Key> parseJwk(final String publicKey) {
final JsonObject jwk;
try {
jwk = Json.createReader(new StringReader(publicKey)).readObject();
} catch (final JsonParsingException e) {
- return Optional.empty();
+ return Collections.emptyList();
}
validateJwk(jwk);
try {
- return Optional.of((RSAPublicKey) JsonWebKey.Factory.newJwk(publicKey).getKey());
+ return Collections.singletonList(JsonWebKey.Factory.newJwk(publicKey).getKey());
} catch (final JoseException e) {
throw new DeploymentException("Could not read MicroProfile Public Key JWK.", e);
}
}
- private Optional<List<RSAPublicKey>> parseJwks(final String publicKey) {
+ private List<Key> parseJwks(final String publicKey) {
final JsonObject jwks;
try {
jwks = Json.createReader(new StringReader(publicKey)).readObject();
} catch (final JsonParsingException e) {
- return Optional.empty();
+ return Collections.emptyList();
}
try {
@@ -260,7 +261,7 @@ public class ConfigurableJWTAuthContextInfo {
.map(JsonWebKey::getKey)
.map(key -> (RSAPublicKey) key)
.collect(Collectors.toList());
- return Optional.of(keys);
+ return Collections.unmodifiableList(keys);
} catch (final JoseException e) {
throw new DeploymentException("Could not read MicroProfile Public Key JWK.", e);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/be942d50/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
index a969515..02132c0 100644
--- 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
@@ -16,52 +16,49 @@
*/
package org.apache.tomee.microprofile.jwt.config;
-import java.security.interfaces.RSAPublicKey;
+import java.security.Key;
+import java.util.Collections;
+import java.util.List;
/**
* The public key and expected issuer needed to validate a token.
*/
public class JWTAuthContextInfo {
-
- private RSAPublicKey signerKey;
+ private List<Key> signerKeys;
private String issuedBy;
private int expGracePeriodSecs = 60;
- public JWTAuthContextInfo() {
+ private JWTAuthContextInfo(final Key signerKey, final String issuedBy) {
+ this.signerKeys = Collections.singletonList(signerKey);
+ this.issuedBy = issuedBy;
}
- public JWTAuthContextInfo(final RSAPublicKey signerKey, final String issuedBy) {
- this.signerKey = signerKey;
+ private JWTAuthContextInfo(final List<Key> signerKeys, final String issuedBy) {
+ this.signerKeys = Collections.unmodifiableList(signerKeys);
this.issuedBy = issuedBy;
}
- public JWTAuthContextInfo(final JWTAuthContextInfo orig) {
- this.signerKey = orig.signerKey;
- this.issuedBy = orig.issuedBy;
- this.expGracePeriodSecs = orig.expGracePeriodSecs;
+ public static JWTAuthContextInfo authContextInfo(final Key signerKey, final String issuedBy) {
+ return new JWTAuthContextInfo(signerKey, issuedBy);
}
- public RSAPublicKey getSignerKey() {
- return signerKey;
+ public static JWTAuthContextInfo authContextInfo(final List<Key> signerKeys, final String issuedBy) {
+ return new JWTAuthContextInfo(signerKeys, issuedBy);
}
- public void setSignerKey(final RSAPublicKey signerKey) {
- this.signerKey = signerKey;
+ public List<Key> getSignerKeys() {
+ return signerKeys;
}
- public String getIssuedBy() {
- return issuedBy;
+ public Key getSignerKey(final String kid) {
+ return signerKeys.get(0);
}
- public void setIssuedBy(final String issuedBy) {
- this.issuedBy = issuedBy;
+ public String getIssuedBy() {
+ return 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/be942d50/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
index feb2008..f19b108 100644
--- 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
@@ -50,7 +50,7 @@ public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory
.setRequireSubject()
.setSkipDefaultAudienceValidation()
.setExpectedIssuer(authContextInfo.getIssuedBy())
- .setVerificationKey(authContextInfo.getSignerKey())
+ .setVerificationKey(authContextInfo.getSignerKey(""))
.setJwsAlgorithmConstraints(
new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
AlgorithmIdentifiers.RSA_USING_SHA256));
@@ -89,4 +89,4 @@ public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory
return principal;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/be942d50/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/JWTAuthContextInfoProvider.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/JWTAuthContextInfoProvider.java
index 6dc1a8f..ee38e49 100644
--- a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/JWTAuthContextInfoProvider.java
+++ b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/JWTAuthContextInfoProvider.java
@@ -33,11 +33,6 @@ 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" +
@@ -51,9 +46,7 @@ public class JWTAuthContextInfoProvider {
final KeyFactory kf = KeyFactory.getInstance("RSA");
final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec);
- contextInfo.setSignerKey(pk);
-
- return Optional.of(contextInfo);
+ return Optional.of(JWTAuthContextInfo.authContextInfo(pk, "https://server.example.com"));
}
@Produces
http://git-wip-us.apache.org/repos/asf/tomee/blob/be942d50/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/TCKTokenParser.java b/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/TCKTokenParser.java
deleted file mode 100644
index e13709d..0000000
--- a/tck/microprofile-tck/jwt/src/test/java/org/apache/tomee/microprofile/tck/jwt/TCKTokenParser.java
+++ /dev/null
@@ -1,40 +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.tck.jwt;
-
-import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
-import org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory;
-import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
-import org.eclipse.microprofile.jwt.JsonWebToken;
-import org.eclipse.microprofile.jwt.tck.util.ITokenParser;
-
-import java.security.PublicKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * MP-JWT TCK harness class to parse a token string
- */
-public class TCKTokenParser implements ITokenParser {
-
- @Override
- 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/be942d50/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
----------------------------------------------------------------------
diff --git a/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser b/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
deleted file mode 100644
index f8d8098..0000000
--- a/tck/microprofile-tck/jwt/src/test/resources/META-INF/services/org.eclipse.microprofile.jwt.tck.util.ITokenParser
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.tomee.microprofile.tck.jwt.TCKTokenParser