Use the JWS/JWE headers properly for JWT tokens.
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/fdb631fa Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/fdb631fa Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/fdb631fa Branch: refs/heads/master Commit: fdb631faedde41ffb308d9aded3eb47d9e9742bd Parents: b889593 Author: Colm O hEigeartaigh <[email protected]> Authored: Wed Nov 4 12:36:46 2015 +0000 Committer: Colm O hEigeartaigh <[email protected]> Committed: Wed Nov 4 12:36:46 2015 +0000 ---------------------------------------------------------------------- .../jose/common/AbstractJoseConsumer.java | 60 -------------------- .../jose/common/AbstractJoseProducer.java | 51 ----------------- .../jose/jwe/JweJwtCompactConsumer.java | 4 ++ .../jose/jwt/AbstractJoseJwtConsumer.java | 57 ++++++++++++++----- .../jose/jwt/AbstractJoseJwtProducer.java | 35 ++++++++++-- 5 files changed, 78 insertions(+), 129 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/fdb631fa/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseConsumer.java deleted file mode 100644 index ddf1d4f..0000000 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseConsumer.java +++ /dev/null @@ -1,60 +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.cxf.rs.security.jose.common; - -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.JwsSignatureVerifier; -import org.apache.cxf.rs.security.jose.jws.JwsUtils; - -public abstract class AbstractJoseConsumer { - private JweDecryptionProvider jweDecryptor; - private JwsSignatureVerifier jwsVerifier; - - public void setJweDecryptor(JweDecryptionProvider jweDecryptor) { - this.jweDecryptor = jweDecryptor; - } - - public JweDecryptionProvider getJweDecryptor() { - return jweDecryptor; - } - - public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { - this.jwsVerifier = theJwsVerifier; - } - - public JwsSignatureVerifier getJwsVerifier() { - return jwsVerifier; - } - - protected JweDecryptionProvider getInitializedDecryptionProvider() { - if (jweDecryptor != null) { - return jweDecryptor; - } - return JweUtils.loadDecryptionProvider(false); - } - protected JwsSignatureVerifier getInitializedSignatureVerifier() { - if (jwsVerifier != null) { - return jwsVerifier; - } - - return JwsUtils.loadSignatureVerifier(false); - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/fdb631fa/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseProducer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseProducer.java deleted file mode 100644 index fe9832f..0000000 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/AbstractJoseProducer.java +++ /dev/null @@ -1,51 +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.cxf.rs.security.jose.common; - -import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.JweUtils; -import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; -import org.apache.cxf.rs.security.jose.jws.JwsUtils; - -public abstract class AbstractJoseProducer { - private JwsSignatureProvider sigProvider; - private JweEncryptionProvider encryptionProvider; - - protected JwsSignatureProvider getInitializedSignatureProvider() { - if (sigProvider != null) { - return sigProvider; - } - - return JwsUtils.loadSignatureProvider(false); - } - protected JweEncryptionProvider getInitializedEncryptionProvider() { - if (encryptionProvider != null) { - return encryptionProvider; - } - return JweUtils.loadEncryptionProvider(false); - } - - public void setEncryptionProvider(JweEncryptionProvider encryptionProvider) { - this.encryptionProvider = encryptionProvider; - } - - public void setSignatureProvider(JwsSignatureProvider signatureProvider) { - this.sigProvider = signatureProvider; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/fdb631fa/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJwtCompactConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJwtCompactConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJwtCompactConsumer.java index d7a76b9..247f84b 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJwtCompactConsumer.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJwtCompactConsumer.java @@ -53,6 +53,10 @@ public class JweJwtCompactConsumer { JwtClaims claims = new JwtTokenReaderWriter().fromJsonClaims(toString(bytes)); return new JwtToken(headers, claims); } + + public JweHeaders getHeaders() { + return headers; + } private static String toString(byte[] bytes) { try { return new String(bytes, "UTF-8"); http://git-wip-us.apache.org/repos/asf/cxf/blob/fdb631fa/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java index df482b8..0eb4a8e 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java @@ -18,25 +18,27 @@ */ package org.apache.cxf.rs.security.jose.jwt; -import org.apache.cxf.rs.security.jose.common.AbstractJoseConsumer; 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.JweJwtCompactConsumer; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; +import org.apache.cxf.rs.security.jose.jws.JwsHeaders; 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; -public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { +public abstract class AbstractJoseJwtConsumer { + private JweDecryptionProvider jweDecryptor; + private JwsSignatureVerifier jwsVerifier; private boolean jwsRequired = true; private boolean jweRequired; - protected JwtToken getJwtToken(String wrappedJwtToken) { return getJwtToken(wrappedJwtToken, null, null); } protected JwtToken getJwtToken(String wrappedJwtToken, - JweDecryptionProvider jweDecryptor, + JweDecryptionProvider theDecryptor, JwsSignatureVerifier theSigVerifier) { if (!isJwsRequired() && !isJweRequired()) { throw new JwtException("Unable to process JWT"); @@ -44,17 +46,20 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { JweHeaders jweHeaders = new JweHeaders(); if (isJweRequired()) { - if (jweDecryptor == null) { - jweDecryptor = getInitializedDecryptionProvider(); + JweJwtCompactConsumer jwtConsumer = new JweJwtCompactConsumer(wrappedJwtToken); + + if (theDecryptor == null) { + theDecryptor = getInitializedDecryptionProvider(jwtConsumer.getHeaders()); } - if (jweDecryptor == null) { + if (theDecryptor == null) { throw new JwtException("Unable to decrypt JWT"); } if (!isJwsRequired()) { - return new JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor); + return jwtConsumer.decryptWith(theDecryptor); } - JweDecryptionOutput decOutput = jweDecryptor.decrypt(wrappedJwtToken); + + JweDecryptionOutput decOutput = theDecryptor.decrypt(wrappedJwtToken); wrappedJwtToken = decOutput.getContentText(); jweHeaders = decOutput.getHeaders(); } @@ -66,7 +71,7 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { if (isJwsRequired()) { if (theSigVerifier == null) { - theSigVerifier = getInitializedSignatureVerifier(jwt); + theSigVerifier = getInitializedSignatureVerifier(jwt.getJwsHeaders()); } if (theSigVerifier == null) { throw new JwtException("Unable to validate JWT"); @@ -80,13 +85,21 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { validateToken(jwt); return jwt; } - protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) { - if (super.getJwsVerifier() != null) { - return super.getJwsVerifier(); + protected JwsSignatureVerifier getInitializedSignatureVerifier(JwsHeaders jwsHeaders) { + if (jwsVerifier != null) { + return jwsVerifier; } - return JwsUtils.loadSignatureVerifier(jwt.getJwsHeaders(), false); + return JwsUtils.loadSignatureVerifier(jwsHeaders, false); } + + protected JweDecryptionProvider getInitializedDecryptionProvider(JweHeaders jweHeaders) { + if (jweDecryptor != null) { + return jweDecryptor; + } + return JweUtils.loadDecryptionProvider(jweHeaders, false); + } + protected void validateToken(JwtToken jwt) { } public boolean isJwsRequired() { @@ -105,4 +118,20 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { this.jweRequired = jweRequired; } + public void setJweDecryptor(JweDecryptionProvider jweDecryptor) { + this.jweDecryptor = jweDecryptor; + } + + public JweDecryptionProvider getJweDecryptor() { + return jweDecryptor; + } + + public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { + this.jwsVerifier = theJwsVerifier; + } + + public JwsSignatureVerifier getJwsVerifier() { + return jwsVerifier; + } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/fdb631fa/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java index a5f5c37..0f72bbe 100644 --- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java +++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java @@ -19,13 +19,18 @@ package org.apache.cxf.rs.security.jose.jwt; import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.rs.security.jose.common.AbstractJoseProducer; import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweHeaders; import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactProducer; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; +import org.apache.cxf.rs.security.jose.jws.JwsHeaders; import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer; import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; -public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { +public abstract class AbstractJoseJwtProducer { + private JwsSignatureProvider sigProvider; + private JweEncryptionProvider encryptionProvider; private boolean jwsRequired = true; private boolean jweRequired; @@ -41,7 +46,7 @@ public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { String data = null; if (isJweRequired() && theEncProvider == null) { - theEncProvider = getInitializedEncryptionProvider(); + theEncProvider = getInitializedEncryptionProvider(jwt.getJweHeaders()); if (theEncProvider == null) { throw new JwtException("Unable to encrypt JWT"); } @@ -53,7 +58,7 @@ public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { data = jws.getSignedEncodedJws(); } else { if (theSigProvider == null) { - theSigProvider = getInitializedSignatureProvider(); + theSigProvider = getInitializedSignatureProvider(jwt.getJwsHeaders()); } if (theSigProvider == null) { @@ -71,6 +76,20 @@ public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { } return data; } + + protected JwsSignatureProvider getInitializedSignatureProvider(JwsHeaders jwsHeaders) { + if (sigProvider != null) { + return sigProvider; + } + + return JwsUtils.loadSignatureProvider(jwsHeaders, false); + } + protected JweEncryptionProvider getInitializedEncryptionProvider(JweHeaders jweHeaders) { + if (encryptionProvider != null) { + return encryptionProvider; + } + return JweUtils.loadEncryptionProvider(jweHeaders, false); + } public boolean isJwsRequired() { return jwsRequired; @@ -87,4 +106,12 @@ public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { public void setJweRequired(boolean jweRequired) { this.jweRequired = jweRequired; } + + public void setEncryptionProvider(JweEncryptionProvider encryptionProvider) { + this.encryptionProvider = encryptionProvider; + } + + public void setSignatureProvider(JwsSignatureProvider signatureProvider) { + this.sigProvider = signatureProvider; + } }
