This is an automated email from the ASF dual-hosted git repository. dblevins pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/main by this push: new 2fd5c701d2 TOMEE-4046 MP JWT 2.1 mp.jwt.decrypt.key.algorithm support new 9766103c0a Merge branch 'main' of github.com:apache/tomee into main 2fd5c701d2 is described below commit 2fd5c701d270e60d1d2ca9fd5afb2833bb5f837e Author: David Blevins <dblev...@tomitribe.com> AuthorDate: Wed Sep 14 18:20:38 2022 -0700 TOMEE-4046 MP JWT 2.1 mp.jwt.decrypt.key.algorithm support --- .../apache/tomee/microprofile/jwt/MPJWTFilter.java | 45 +++++++++++++++----- .../jwt/config/JWTAuthConfiguration.java | 48 +++++++++++++++++----- .../jwt/config/JWTAuthConfigurationProperties.java | 4 +- 3 files changed, 74 insertions(+), 23 deletions(-) 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 da951b974c..8793823770 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 @@ -44,6 +44,7 @@ import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipal; import org.eclipse.microprofile.jwt.Claims; import org.eclipse.microprofile.jwt.JsonWebToken; import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers; import org.jose4j.jwk.JsonWebKey; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jwt.JwtClaims; @@ -377,16 +378,39 @@ public class MPJWTFilter implements Filter { try { final JwtConsumerBuilder builder = new JwtConsumerBuilder() .setRelaxVerificationKeyValidation() - .setRequireSubject() - .setJwsAlgorithmConstraints( - new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, - AlgorithmIdentifiers.RSA_USING_SHA256, - AlgorithmIdentifiers.RSA_USING_SHA384, - AlgorithmIdentifiers.RSA_USING_SHA512, - AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256, - AlgorithmIdentifiers.ECDSA_USING_P384_CURVE_AND_SHA384, - AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512 - )); + .setRequireSubject(); + + if (authContextInfo.getSignatureAlgorithm() != null) { + builder.setJwsAlgorithmConstraints( + new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, + authContextInfo.getSignatureAlgorithm() + )); + } else { + builder.setJwsAlgorithmConstraints( + new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, + AlgorithmIdentifiers.RSA_USING_SHA256, + AlgorithmIdentifiers.RSA_USING_SHA384, + AlgorithmIdentifiers.RSA_USING_SHA512, + AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256, + AlgorithmIdentifiers.ECDSA_USING_P384_CURVE_AND_SHA384, + AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512 + )); + } + + if (authContextInfo.getDecryptAlgorithm() != null) { + builder.setJweAlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, + authContextInfo.getDecryptAlgorithm() + ); + } else { + builder.setJweAlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, + KeyManagementAlgorithmIdentifiers.RSA_OAEP, + KeyManagementAlgorithmIdentifiers.RSA_OAEP_256, + KeyManagementAlgorithmIdentifiers.ECDH_ES, + KeyManagementAlgorithmIdentifiers.ECDH_ES_A128KW, + KeyManagementAlgorithmIdentifiers.ECDH_ES_A192KW, + KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW + ); + } if (authContextInfo.getAudiences().length > 0) { builder.setExpectedAudience(true, authContextInfo.getAudiences()); @@ -422,7 +446,6 @@ public class MPJWTFilter implements Filter { } - final JwtConsumer jwtConsumer = builder.build(); final JwtContext jwtContext = jwtConsumer.process(token); final String type = jwtContext.getJoseObjects().get(0).getHeader("typ"); diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfiguration.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfiguration.java index 96986b2d02..000fa648e3 100644 --- a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfiguration.java +++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfiguration.java @@ -26,17 +26,34 @@ import java.util.Map; public class JWTAuthConfiguration { public static final String DEFAULT_KEY = "DEFAULT"; - private Map<String, Key> publicKeys; - private Map<String, Key> decryptKeys; - private String[] audiences; - private String issuer; - private int expGracePeriodSecs = 60; - private String headerName = "Authorization"; - private String headerScheme = "Bearer"; - private boolean allowNoExpiryClaim = false; - private String cookieName = "Bearer"; - - public JWTAuthConfiguration(final Map<String, Key> publicKeys, final String issuer, final boolean allowNoExpiryClaim, final String[] audiences, final Map<String, Key> decryptKeys, final String header, final String cookie) { + private final Map<String, Key> publicKeys; + private final Map<String, Key> decryptKeys; + private final String[] audiences; + private final String issuer; + private final int expGracePeriodSecs = 60; + private final String headerName; + private final String headerScheme = "Bearer"; + private final boolean allowNoExpiryClaim; + private final String cookieName; + + /** + * mp.jwt.verify.publickey.algorithm + * + * The mp.jwt.verify.publickey.algorithm configuration property allows for + * specifying which Public Key Signature Algorithm is supported by the MP JWT endpoint. + */ + private String signatureAlgorithm; + + /** + * mp.jwt.decrypt.key.algorithm + * + * The mp.jwt.decrypt.key.algorithm configuration property allows for specifying which key + * management key algorithm is supported by the MP JWT endpoint. Algorithms which must be + * supported are either RSA-OAEP or RSA-OAEP-256. + */ + private String decryptAlgorithm; + + public JWTAuthConfiguration(final Map<String, Key> publicKeys, final String issuer, final boolean allowNoExpiryClaim, final String[] audiences, final Map<String, Key> decryptKeys, final String header, final String cookie, final String decryptAlgorithm, final String signatureAlgorithm) { if (publicKeys == null) { this.publicKeys = Collections.EMPTY_MAP; } else if (publicKeys.size() == 1) { @@ -57,6 +74,8 @@ public class JWTAuthConfiguration { this.audiences = audiences; this.headerName = header; this.cookieName = cookie; + this.decryptAlgorithm = decryptAlgorithm; + this.signatureAlgorithm = signatureAlgorithm; } public String getCookieName() { @@ -99,4 +118,11 @@ public class JWTAuthConfiguration { return allowNoExpiryClaim; } + public String getSignatureAlgorithm() { + return signatureAlgorithm; + } + + public String getDecryptAlgorithm() { + return decryptAlgorithm; + } } diff --git a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java index cf204b7aaf..31818fceee 100644 --- a/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java +++ b/mp-jwt/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthConfigurationProperties.java @@ -110,7 +110,9 @@ public class JWTAuthConfigurationProperties { audiences.toArray(new String[0]), decryptkeys, config.getOptionalValue(TOKEN_HEADER, String.class).map(String::toLowerCase).orElse("authorization"), - config.getOptionalValue(TOKEN_COOKIE, String.class).map(String::toLowerCase).orElse("bearer")); + config.getOptionalValue(TOKEN_COOKIE, String.class).map(String::toLowerCase).orElse("bearer"), + config.getOptionalValue("mp.jwt.decrypt.key.algorithm", String.class).orElse( null), + config.getOptionalValue("mp.jwt.verify.publickey.algorithm", String.class).orElse( null)); } }