Repository: cxf Updated Branches: refs/heads/master 9dfb278c7 -> efaf05170
Updating Jws/Jwe provider initialization code Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/efaf0517 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/efaf0517 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/efaf0517 Branch: refs/heads/master Commit: efaf05170b4f76ad61ff423e30ece58bdd226ae5 Parents: 9dfb278 Author: Sergey Beryozkin <sberyoz...@talend.com> Authored: Fri Nov 28 12:18:28 2014 +0000 Committer: Sergey Beryozkin <sberyoz...@talend.com> Committed: Fri Nov 28 12:18:28 2014 +0000 ---------------------------------------------------------------------- parent/pom.xml | 2 +- .../jose/jaxrs/AbstractJweDecryptingFilter.java | 13 +------ .../jose/jaxrs/AbstractJwsReaderProvider.java | 15 +------- .../jose/jaxrs/AbstractJwsWriterProvider.java | 12 +----- .../jose/jaxrs/JweWriterInterceptor.java | 12 +----- .../cxf/rs/security/jose/jwe/JweUtils.java | 35 +++++++++++++++++ .../cxf/rs/security/jose/jws/JwsUtils.java | 38 ++++++++++++++++++- .../cxf/rs/security/jose/jwt/JwtUtils.java | 15 ++++++-- .../grants/code/JwtRequestCodeFilter.java | 33 +++++++++++++--- .../oauth2/grants/jwt/AbstractJwtHandler.java | 17 ++++++--- .../oidc/rp/AbstractTokenValidator.java | 40 ++++++++++---------- 11 files changed, 148 insertions(+), 84 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/parent/pom.xml ---------------------------------------------------------------------- diff --git a/parent/pom.xml b/parent/pom.xml index a9de550..d396e4c 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -107,7 +107,7 @@ <cxf.jaxb.xjc.version>2.2.10-b140310.1920</cxf.jaxb.xjc.version> <cxf.joda.time.version>2.2</cxf.joda.time.version> <cxf.jdom.version>1.0</cxf.jdom.version> - <cxf.jettison.version>1.3.6</cxf.jettison.version> + <cxf.jettison.version>1.3.8-SNAPSHOT</cxf.jettison.version> <cxf.jetty8.version>8.1.15.v20140411</cxf.jetty8.version> <cxf.jetty9.version>9.2.3.v20140905</cxf.jetty9.version> <cxf.jetty.version>${cxf.jetty9.version}</cxf.jetty.version> http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java index 83e00e1..03c024e 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java @@ -22,17 +22,12 @@ import java.io.IOException; import java.io.InputStream; import org.apache.cxf.helpers.IOUtils; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import org.apache.cxf.message.Message; -import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput; import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; import org.apache.cxf.rs.security.jose.jwe.JweHeaders; import org.apache.cxf.rs.security.jose.jwe.JweUtils; public class AbstractJweDecryptingFilter { - private static final String RSSEC_ENCRYPTION_IN_PROPS = "rs.security.encryption.in.properties"; - private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties"; private JweDecryptionProvider decryption; private String defaultMediaType; protected JweDecryptionOutput decrypt(InputStream is) throws IOException { @@ -52,13 +47,7 @@ public class AbstractJweDecryptingFilter { if (decryption != null) { return decryption; } - Message m = JAXRSUtils.getCurrentMessage(); - String propLoc = - (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_IN_PROPS, RSSEC_ENCRYPTION_PROPS); - if (propLoc == null) { - throw new SecurityException(); - } - return JweUtils.loadDecryptionProvider(propLoc, m); + return JweUtils.loadDecryptionProvider(true); } public String getDefaultMediaType() { return defaultMediaType; http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java index 6027e60..441f4bb 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java @@ -18,16 +18,10 @@ */ package org.apache.cxf.rs.security.jose.jaxrs; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import org.apache.cxf.message.Message; -import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; import org.apache.cxf.rs.security.jose.jws.JwsUtils; public class AbstractJwsReaderProvider { - private static final String RSSEC_SIGNATURE_IN_PROPS = "rs.security.signature.in.properties"; - private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties"; - private JwsSignatureVerifier sigVerifier; private String defaultMediaType; @@ -39,14 +33,7 @@ public class AbstractJwsReaderProvider { if (sigVerifier != null) { return sigVerifier; } - - Message m = JAXRSUtils.getCurrentMessage(); - String propLoc = - (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_IN_PROPS, RSSEC_SIGNATURE_PROPS); - if (propLoc == null) { - throw new SecurityException(); - } - return JwsUtils.loadSignatureVerifier(propLoc, m); + return JwsUtils.loadSignatureVerifier(true); } public String getDefaultMediaType() { http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java index 139f20f..d281b2e 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java @@ -24,17 +24,13 @@ import java.io.OutputStream; import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.helpers.IOUtils; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.message.Message; -import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.JoseHeaders; import org.apache.cxf.rs.security.jose.jws.JwsCompactProducer; import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; import org.apache.cxf.rs.security.jose.jws.JwsUtils; public class AbstractJwsWriterProvider { - private static final String RSSEC_SIGNATURE_OUT_PROPS = "rs.security.signature.out.properties"; - private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties"; private static final String JWS_CONTEXT_PROPERTY = "org.apache.cxf.jws.context"; private JwsSignatureProvider sigProvider; @@ -46,13 +42,7 @@ public class AbstractJwsWriterProvider { if (sigProvider != null) { return sigProvider; } - Message m = JAXRSUtils.getCurrentMessage(); - String propLoc = - (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_OUT_PROPS, RSSEC_SIGNATURE_PROPS); - if (propLoc == null) { - throw new SecurityException(); - } - JwsSignatureProvider theSigProvider = JwsUtils.loadSignatureProvider(propLoc, m); + JwsSignatureProvider theSigProvider = JwsUtils.loadSignatureProvider(true); headers.setAlgorithm(theSigProvider.getAlgorithm()); return theSigProvider; } http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java index a80ac67..f762541 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java @@ -34,8 +34,6 @@ import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import org.apache.cxf.message.Message; -import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.JoseConstants; import org.apache.cxf.rs.security.jose.JoseHeadersReaderWriter; import org.apache.cxf.rs.security.jose.JoseHeadersWriter; @@ -48,8 +46,6 @@ import org.apache.cxf.rs.security.jose.jwe.JweUtils; @Priority(Priorities.JWE_WRITE_PRIORITY) public class JweWriterInterceptor implements WriterInterceptor { - private static final String RSSEC_ENCRYPTION_OUT_PROPS = "rs.security.encryption.out.properties"; - private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties"; private JweEncryptionProvider encryptionProvider; private boolean contentTypeRequired = true; private boolean useJweOutputStream; @@ -118,13 +114,7 @@ public class JweWriterInterceptor implements WriterInterceptor { if (encryptionProvider != null) { return encryptionProvider; } - Message m = JAXRSUtils.getCurrentMessage(); - String propLoc = - (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_OUT_PROPS, RSSEC_ENCRYPTION_PROPS); - if (propLoc == null) { - throw new SecurityException(); - } - return JweUtils.loadEncryptionProvider(propLoc, m); + return JweUtils.loadEncryptionProvider(true); } public void setUseJweOutputStream(boolean useJweOutputStream) { http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java index c7a5378..7f9a8aa 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java @@ -25,8 +25,10 @@ import java.util.Properties; import javax.crypto.SecretKey; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.JoseConstants; import org.apache.cxf.rs.security.jose.JoseHeaders; import org.apache.cxf.rs.security.jose.JoseUtils; @@ -39,6 +41,10 @@ public final class JweUtils { private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm"; private static final String JSON_WEB_ENCRYPTION_KEY_ALGO_PROP = "rs.security.jwe.key.encryption.algorithm"; private static final String JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP = "rs.security.jwe.zip.algorithm"; + private static final String RSSEC_ENCRYPTION_OUT_PROPS = "rs.security.encryption.out.properties"; + private static final String RSSEC_ENCRYPTION_IN_PROPS = "rs.security.encryption.in.properties"; + private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties"; + private JweUtils() { } @@ -130,6 +136,7 @@ public final class JweUtils { public static KeyDecryptionAlgorithm getKeyDecryptionAlgorithm(JsonWebKey jwk) { return getKeyDecryptionAlgorithm(jwk, null); } + public static KeyDecryptionAlgorithm getKeyDecryptionAlgorithm(JsonWebKey jwk, String defaultAlgorithm) { String keyEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm(); KeyDecryptionAlgorithm keyDecryptionProvider = null; @@ -208,6 +215,20 @@ public final class JweUtils { return new DirectKeyJweDecryption(JwkUtils.toSecretKey(key), getContentDecryptionAlgorithm(key.getAlgorithm())); } + public static JweEncryptionProvider loadEncryptionProvider(boolean required) { + Message m = JAXRSUtils.getCurrentMessage(); + if (m != null) { + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_OUT_PROPS, RSSEC_ENCRYPTION_PROPS); + if (propLoc != null) { + return loadEncryptionProvider(propLoc, m); + } + } + if (required) { + throw new SecurityException(); + } + return null; + } public static JweEncryptionProvider loadEncryptionProvider(String propLoc, Message m) { KeyEncryptionAlgorithm keyEncryptionProvider = null; String keyEncryptionAlgo = null; @@ -240,6 +261,20 @@ public final class JweUtils { contentEncryptionAlgo, props.getProperty(JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP)); } + public static JweDecryptionProvider loadDecryptionProvider(boolean required) { + Message m = JAXRSUtils.getCurrentMessage(); + if (m != null) { + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_IN_PROPS, RSSEC_ENCRYPTION_PROPS); + if (propLoc != null) { + return loadDecryptionProvider(propLoc, m); + } + } + if (required) { + throw new SecurityException(); + } + return null; + } public static JweDecryptionProvider loadDecryptionProvider(String propLoc, Message m) { KeyDecryptionAlgorithm keyDecryptionProvider = null; Properties props = null; http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java index 9e2edf0..8bab845 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java @@ -28,8 +28,10 @@ import java.util.Properties; import javax.ws.rs.core.MultivaluedMap; import org.apache.cxf.jaxrs.impl.MetadataMap; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.jose.JoseHeaders; import org.apache.cxf.rs.security.jose.JoseUtils; import org.apache.cxf.rs.security.jose.jaxrs.KeyManagementUtils; @@ -39,12 +41,17 @@ import org.apache.cxf.rs.security.jose.jwk.JwkUtils; public final class JwsUtils { private static final String JSON_WEB_SIGNATURE_ALGO_PROP = "rs.security.jws.content.signature.algorithm"; + private static final String RSSEC_SIGNATURE_OUT_PROPS = "rs.security.signature.out.properties"; + private static final String RSSEC_SIGNATURE_IN_PROPS = "rs.security.signature.in.properties"; + private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties"; private JwsUtils() { } public static String sign(RSAPrivateKey key, String algo, String content) { return sign(key, algo, content, null); } + + public static String sign(RSAPrivateKey key, String algo, String content, String ct) { return sign(getRSAKeySignatureProvider(key, algo), content, ct); } @@ -71,6 +78,8 @@ public final class JwsUtils { if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) { theSigProvider = getRSAKeySignatureProvider(JwkUtils.toRSAPrivateKey(jwk), rsaSignatureAlgo); + + } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) { byte[] key = JoseUtils.decode((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE)); theSigProvider = getHmacSignatureProvider(key, rsaSignatureAlgo); @@ -122,10 +131,37 @@ public final class JwsUtils { } return map; } + public static JwsSignatureProvider loadSignatureProvider(boolean required) { + Message m = JAXRSUtils.getCurrentMessage(); + if (m != null) { + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_OUT_PROPS, RSSEC_SIGNATURE_PROPS); + if (propLoc != null) { + return loadSignatureProvider(propLoc, m); + } + } + if (required) { + throw new SecurityException(); + } + return null; + } public static JwsSignatureProvider loadSignatureProvider(String propLoc, Message m) { return loadSignatureProvider(propLoc, m, false); } - + public static JwsSignatureVerifier loadSignatureVerifier(boolean required) { + Message m = JAXRSUtils.getCurrentMessage(); + if (m != null) { + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_IN_PROPS, RSSEC_SIGNATURE_PROPS); + if (propLoc != null) { + return loadSignatureVerifier(propLoc, m); + } + } + if (required) { + throw new SecurityException(); + } + return null; + } public static List<JwsSignatureProvider> loadSignatureProviders(String propLoc, Message m) { Properties props = loadProperties(m, propLoc); JwsSignatureProvider theSigProvider = loadSignatureProvider(propLoc, m, true); http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java index 582a7e7..6b620de 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java @@ -41,15 +41,24 @@ public final class JwtUtils { } return reader.fromJsonClaims(json); } - public static void validateJwtTimeClaims(JwtClaims claims) { + + public static void validateJwtTimeClaims(JwtClaims claims, int issuedAtRange, boolean claimsRequired) { Long currentTimeInSecs = System.currentTimeMillis() / 1000; Long expiryTimeInSecs = claims.getExpiryTime(); - if (expiryTimeInSecs != null && currentTimeInSecs > expiryTimeInSecs) { + if (expiryTimeInSecs == null && claimsRequired + || expiryTimeInSecs != null && currentTimeInSecs > expiryTimeInSecs) { throw new SecurityException("The token expired"); } Long issuedAtInSecs = claims.getIssuedAt(); - if (issuedAtInSecs != null && issuedAtInSecs > currentTimeInSecs) { + if (issuedAtInSecs == null && claimsRequired + || issuedAtInSecs != null && (issuedAtInSecs > currentTimeInSecs || issuedAtRange > 0 + && issuedAtInSecs < currentTimeInSecs - issuedAtRange)) { throw new SecurityException("Invalid issuedAt"); } } + + public static void validateJwtTimeClaims(JwtClaims claims) { + validateJwtTimeClaims(claims, 0, false); + } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JwtRequestCodeFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JwtRequestCodeFilter.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JwtRequestCodeFilter.java index 5beb360..3f1a310 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JwtRequestCodeFilter.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/JwtRequestCodeFilter.java @@ -24,12 +24,15 @@ import javax.ws.rs.core.MultivaluedMap; import org.apache.cxf.jaxrs.impl.MetadataMap; import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer; import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.UserSubject; import org.apache.cxf.rs.security.oauth2.provider.AuthorizationCodeRequestFilter; +import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; public class JwtRequestCodeFilter implements AuthorizationCodeRequestFilter { private static final String REQUEST_PARAM = "request"; @@ -41,17 +44,22 @@ public class JwtRequestCodeFilter implements AuthorizationCodeRequestFilter { Client client) { String requestToken = params.getFirst(REQUEST_PARAM); if (requestToken != null) { - // there may be Client specific keys so we can have a map of - // client id to JWS and JWE handlers - if (jweDecryptor != null) { - requestToken = jweDecryptor.decrypt(requestToken).getContentText(); + JweDecryptionProvider theJweDecryptor = getInitializedDecryptionProvider(); + if (theJweDecryptor != null) { + requestToken = theJweDecryptor.decrypt(requestToken).getContentText(); } + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); JwsJwtCompactConsumer consumer = new JwsJwtCompactConsumer(requestToken); - if (!consumer.verifySignatureWith(jwsVerifier)) { + if (!consumer.verifySignatureWith(theSigVerifier)) { throw new SecurityException("Invalid Signature"); } JwtClaims claims = consumer.getJwtClaims(); - // TODO: validate claim issuer and audience + //TODO: 'iss' may be different to a client id + if (!client.getClientId().equals(claims.getIssuer()) + || claims.getClaim(OAuthConstants.CLIENT_ID) != null + && claims.getStringProperty(OAuthConstants.CLIENT_ID).equals(client.getClientId())) { + throw new SecurityException(); + } MultivaluedMap<String, String> newParams = new MetadataMap<String, String>(); Map<String, Object> claimsMap = claims.asMap(); for (Map.Entry<String, Object> entry : claimsMap.entrySet()) { @@ -69,4 +77,17 @@ public class JwtRequestCodeFilter implements AuthorizationCodeRequestFilter { public void setJweVerifier(JwsSignatureVerifier theJwsVerifier) { this.jwsVerifier = theJwsVerifier; } + + protected JweDecryptionProvider getInitializedDecryptionProvider() { + if (jweDecryptor != null) { + return jweDecryptor; + } + return JweUtils.loadDecryptionProvider(false); + } + protected JwsSignatureVerifier getInitializedSigVerifier() { + if (jwsVerifier != null) { + return jwsVerifier; + } + return JwsUtils.loadSignatureVerifier(true); + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/AbstractJwtHandler.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/AbstractJwtHandler.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/AbstractJwtHandler.java index a7677e6..5b31366 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/AbstractJwtHandler.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/AbstractJwtHandler.java @@ -23,6 +23,7 @@ import java.util.Set; import org.apache.cxf.rs.security.jose.JoseHeaders; import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.jose.jwt.JwtUtils; import org.apache.cxf.rs.security.oauth2.common.Client; @@ -36,14 +37,15 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; */ public abstract class AbstractJwtHandler extends AbstractGrantHandler { private Set<String> supportedIssuers; - private JwsSignatureVerifier jwsVefifier; + private JwsSignatureVerifier jwsVerifier; protected AbstractJwtHandler(List<String> grants) { super(grants); } protected void validateSignature(JoseHeaders headers, String unsignedText, byte[] signature) { - if (jwsVefifier.verify(headers, unsignedText, signature)) { + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); + if (theSigVerifier.verify(headers, unsignedText, signature)) { throw new OAuthServiceException(OAuthConstants.INVALID_GRANT); } } @@ -71,8 +73,13 @@ public abstract class AbstractJwtHandler extends AbstractGrantHandler { this.supportedIssuers = supportedIssuers; } - public void setJwsVefifier(JwsSignatureVerifier jwsVefifier) { - this.jwsVefifier = jwsVefifier; + public void setJwsVerifier(JwsSignatureVerifier jwsVerifier) { + this.jwsVerifier = jwsVerifier; + } + protected JwsSignatureVerifier getInitializedSigVerifier() { + if (jwsVerifier != null) { + return jwsVerifier; + } + return JwsUtils.loadSignatureVerifier(true); } - } http://git-wip-us.apache.org/repos/asf/cxf/blob/efaf0517/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java index 89e7fa4..9c26804 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java @@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactConsumer; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys; import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer; @@ -30,6 +31,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; import org.apache.cxf.rs.security.jose.jws.JwsUtils; import org.apache.cxf.rs.security.jose.jwt.JwtClaims; import org.apache.cxf.rs.security.jose.jwt.JwtToken; +import org.apache.cxf.rs.security.jose.jwt.JwtUtils; public abstract class AbstractTokenValidator { private JweDecryptionProvider jweDecryptor; @@ -44,14 +46,12 @@ public abstract class AbstractTokenValidator { if (wrappedJwtToken == null) { throw new SecurityException("ID Token is missing"); } - // Decrypt the token if needed - if (jweDecryptor != null) { + JweDecryptionProvider theJweDecryptor = getInitializedDecryptionProvider(jweOnly); + if (theJweDecryptor != null) { if (jweOnly) { return new JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor); } wrappedJwtToken = jweDecryptor.decrypt(wrappedJwtToken).getContentText(); - } else if (jweOnly) { - throw new SecurityException("Token can not be decrypted"); } // validate token signature @@ -74,27 +74,16 @@ public abstract class AbstractTokenValidator { if (issuerId == null && validateClaimsAlways || issuerId != null && !issuerId.equals(issuer)) { throw new SecurityException("Invalid provider"); } - Long currentTimeInSecs = System.currentTimeMillis() / 1000; - Long expiryTimeInSecs = claims.getExpiryTime(); - if (expiryTimeInSecs == null && validateClaimsAlways - || expiryTimeInSecs != null && currentTimeInSecs > expiryTimeInSecs) { - throw new SecurityException("The token expired"); - } - Long issuedAtInSecs = claims.getIssuedAt(); - if (issuedAtInSecs == null && validateClaimsAlways - || issuedAtInSecs != null && (issuedAtInSecs > currentTimeInSecs || issuedAtRange > 0 - && issuedAtInSecs < currentTimeInSecs - issuedAtRange)) { - throw new SecurityException("Invalid issuedAt"); - } - + JwtUtils.validateJwtTimeClaims(claims, issuedAtRange, validateClaimsAlways); } protected JwtToken getTokenValidateSignature(String wrappedJwtToken, String idTokenKid) { // read id_token into JwtToken JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken); JwtToken jwt = jwtConsumer.getJwtToken(); - if (jwsVerifier != null) { - return validateToken(jwtConsumer, jwt, jwsVerifier); + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); + if (theSigVerifier != null) { + return validateToken(jwtConsumer, jwt, theSigVerifier); } if (jwkSetClient == null) { throw new SecurityException("Provider Jwk Set Client is not available"); @@ -140,5 +129,16 @@ public abstract class AbstractTokenValidator { this.issuedAtRange = issuedAtRange; } - + protected JweDecryptionProvider getInitializedDecryptionProvider(boolean jweOnly) { + if (jweDecryptor != null) { + return jweDecryptor; + } + return JweUtils.loadDecryptionProvider(jweOnly); + } + protected JwsSignatureVerifier getInitializedSigVerifier() { + if (jwsVerifier != null) { + return jwsVerifier; + } + return JwsUtils.loadSignatureVerifier(false); + } }