Repository: cxf Updated Branches: refs/heads/master e9ede319d -> 9fc3be7e5
Trying to consolidate various abstract jose support code Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/9fc3be7e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/9fc3be7e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/9fc3be7e Branch: refs/heads/master Commit: 9fc3be7e5afe6d2a06a4be37fada1ac14f9c4f86 Parents: e9ede31 Author: Sergey Beryozkin <[email protected]> Authored: Wed Jul 29 16:11:37 2015 +0300 Committer: Sergey Beryozkin <[email protected]> Committed: Wed Jul 29 16:11:37 2015 +0300 ---------------------------------------------------------------------- .../rs/security/jose/AbstractJoseConsumer.java | 51 ++++++++++ .../rs/security/jose/AbstractJoseProducer.java | 51 ++++++++++ .../cxf/rs/security/jose/JoseHeaders.java | 2 +- .../jaxrs/JwtAuthenticationClientFilter.java | 7 +- .../jose/jaxrs/JwtAuthenticationFilter.java | 7 +- .../jose/jwt/AbstractJoseJwtConsumer.java | 64 ++++++------- .../jose/jwt/AbstractJoseJwtProducer.java | 64 +++++++------ .../cxf/rs/security/jose/jwt/JwtToken.java | 3 + .../provider/AbstractOAuthJoseJwtProducer.java | 87 +++++++++++++++++ .../jwt/AbstactJwtAccessTokenValidator.java | 8 +- .../oidc/idp/AbstractJwsJweProducer.java | 99 -------------------- .../oidc/idp/IdTokenCodeResponseFilter.java | 19 +--- .../rs/security/oidc/idp/UserInfoService.java | 25 +---- .../oidc/rp/AbstractTokenValidator.java | 9 +- 14 files changed, 282 insertions(+), 214 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java new file mode 100644 index 0000000..64e5f16 --- /dev/null +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java @@ -0,0 +1,51 @@ +/** + * 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; + +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 void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { + this.jwsVerifier = theJwsVerifier; + } + + protected JweDecryptionProvider getInitializedDecryptionProvider(boolean required) { + if (jweDecryptor != null) { + return jweDecryptor; + } + return JweUtils.loadDecryptionProvider(required); + } + protected JwsSignatureVerifier getInitializedSignatureVerifier(boolean required) { + if (jwsVerifier != null) { + return jwsVerifier; + } + return JwsUtils.loadSignatureVerifier(required); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java new file mode 100644 index 0000000..c590ef9 --- /dev/null +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java @@ -0,0 +1,51 @@ +/** + * 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; + +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(boolean required) { + if (sigProvider != null) { + return sigProvider; + } + + return JwsUtils.loadSignatureProvider(required); + } + protected JweEncryptionProvider getInitializedEncryptionProvider(boolean required) { + if (encryptionProvider != null) { + return encryptionProvider; + } + return JweUtils.loadEncryptionProvider(required); + } + + 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/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java index fd111e6..66c7863 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java @@ -26,7 +26,7 @@ import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.jaxrs.provider.json.JsonMapObject; import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; -public abstract class JoseHeaders extends JsonMapObject { +public class JoseHeaders extends JsonMapObject { public JoseHeaders() { } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java index ecfe44f..531d92a 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java @@ -44,8 +44,7 @@ public class JwtAuthenticationClientFilter extends AbstractJoseJwtProducer @Override public void filter(ClientRequestContext requestContext) throws IOException { JwtToken jwt = getJwtToken(requestContext); - boolean jweRequired = false; - if (jwt == null) { + if (jwt == null && super.isJweRequired()) { AuthorizationPolicy ap = JAXRSUtils.getCurrentMessage().getExchange() .getEndpoint().getEndpointInfo().getExtensor(AuthorizationPolicy.class); if (ap != null && ap.getUserName() != null) { @@ -54,7 +53,6 @@ public class JwtAuthenticationClientFilter extends AbstractJoseJwtProducer claims.setClaim("password", ap.getPassword()); claims.setIssuedAt(System.currentTimeMillis() / 1000); jwt = new JwtToken(new JweHeaders(), claims); - jweRequired = true; } } if (jwt == null) { @@ -62,7 +60,7 @@ public class JwtAuthenticationClientFilter extends AbstractJoseJwtProducer } JoseUtils.setJoseMessageContextProperty(jwt.getHeaders(), getContextPropertyValue()); - String data = super.processJwt(jwt, true, jweRequired); + String data = super.processJwt(jwt); requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, "JWT " + data); } @@ -72,4 +70,5 @@ public class JwtAuthenticationClientFilter extends AbstractJoseJwtProducer protected String getContextPropertyValue() { return Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(16)); } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java index 7146679..b19582b 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java @@ -42,7 +42,6 @@ import org.apache.cxf.security.SecurityContext; @Priority(Priorities.AUTHENTICATION) public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements ContainerRequestFilter { protected static final Logger LOG = LogUtils.getL7dLogger(JwtAuthenticationFilter.class); - private boolean jweOnly; @Override public void filter(ContainerRequestContext requestContext) throws IOException { @@ -51,15 +50,11 @@ public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer implements if (parts == null || !"JWT".equals(parts[0]) || parts.length != 2) { throw new JoseException("JWT scheme is expected"); } - JwtToken jwt = super.getJwtToken(parts[1], jweOnly); + JwtToken jwt = super.getJwtToken(parts[1]); JoseUtils.setMessageContextProperty(jwt.getHeaders()); JAXRSUtils.getCurrentMessage().put(SecurityContext.class, new SimpleSecurityContext(new JwtPrincipal(jwt))); } - - public void setJweOnly(boolean jweOnly) { - this.jweOnly = jweOnly; - } public static class JwtPrincipal extends SimplePrincipal { private static final long serialVersionUID = 1L; private JwtToken jwt; http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java index 34dd60c..fc00c81 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java @@ -18,56 +18,54 @@ */ package org.apache.cxf.rs.security.jose.jwt; +import org.apache.cxf.rs.security.jose.AbstractJoseConsumer; +import org.apache.cxf.rs.security.jose.JoseException; 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.jws.JwsJwtCompactConsumer; import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; -import org.apache.cxf.rs.security.jose.jws.JwsUtils; -public abstract class AbstractJoseJwtConsumer { - private JweDecryptionProvider jweDecryptor; - private JwsSignatureVerifier jwsVerifier; - protected JwtToken getJwtToken(String wrappedJwtToken, boolean jweOnly) { - JweDecryptionProvider theJweDecryptor = getInitializedDecryptionProvider(jweOnly); - if (theJweDecryptor != null) { - if (jweOnly) { +public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { + private boolean jwsRequired = true; + private boolean jweRequired = true; + + protected JwtToken getJwtToken(String wrappedJwtToken) { + if (!isJwsRequired() && !isJweRequired()) { + throw new JoseException("Unable to process JWT"); + } + JweDecryptionProvider jweDecryptor = getInitializedDecryptionProvider(isJweRequired()); + if (jweDecryptor != null) { + if (!isJwsRequired()) { return new JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor); } wrappedJwtToken = jweDecryptor.decrypt(wrappedJwtToken).getContentText(); - } else if (jweOnly) { - throw new SecurityException(); - } + } JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken); - JwtToken jwt = jwtConsumer.getJwtToken(); - JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); - return validateToken(jwtConsumer, jwt, theSigVerifier); - } - protected JwtToken validateToken(JwsJwtCompactConsumer consumer, JwtToken jwt, JwsSignatureVerifier jws) { - if (!consumer.verifySignatureWith(jws)) { + JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(isJwsRequired()); + if (!jwtConsumer.verifySignatureWith(theSigVerifier)) { throw new SecurityException("Invalid Signature"); } - return jwt; + JwtToken jwt = jwtConsumer.getJwtToken(); + validateToken(jwt); + return jwt; + } + protected void validateToken(JwtToken jwt) { } - public void setJweDecryptor(JweDecryptionProvider jweDecryptor) { - this.jweDecryptor = jweDecryptor; + public boolean isJwsRequired() { + return jwsRequired; } - public void setJweVerifier(JwsSignatureVerifier theJwsVerifier) { - this.jwsVerifier = theJwsVerifier; + public void setJwsRequired(boolean jwsRequired) { + this.jwsRequired = jwsRequired; } - protected JweDecryptionProvider getInitializedDecryptionProvider(boolean jweOnly) { - if (jweDecryptor != null) { - return jweDecryptor; - } - return JweUtils.loadDecryptionProvider(jweOnly); + public boolean isJweRequired() { + return jweRequired; } - protected JwsSignatureVerifier getInitializedSigVerifier() { - if (jwsVerifier != null) { - return jwsVerifier; - } - return JwsUtils.loadSignatureVerifier(true); + + public void setJweRequired(boolean jweRequired) { + this.jweRequired = jweRequired; } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java index 80318fb..bd2e1da 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java @@ -19,40 +19,50 @@ package org.apache.cxf.rs.security.jose.jwt; import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.rs.security.jose.AbstractJoseProducer; +import org.apache.cxf.rs.security.jose.JoseException; 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.jwe.JweJwtCompactProducer; 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; -import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider; -public abstract class AbstractJoseJwtProducer { - private JwsSignatureProvider sigProvider; - private JweEncryptionProvider encryptionProvider; - protected String processJwt(JwtToken jwt, boolean jwsRequired, boolean jweRequired) { - JwsJwtCompactProducer jws = new JwsJwtCompactProducer(jwt); - JwsSignatureProvider theSigProvider = getInitializedSigProvider(jweRequired, jwsRequired); - String data = jws.signWith(theSigProvider); - JweEncryptionProvider theEncProvider = getInitializedEncryptionProvider(jweRequired); - if (theEncProvider != null) { - data = theEncProvider.encrypt(StringUtils.toBytesUTF8(data), null); +public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { + private boolean jwsRequired = true; + private boolean jweRequired = true; + + protected String processJwt(JwtToken jwt) { + if (!isJwsRequired() && !isJweRequired()) { + throw new JoseException("Unable to secure JWT"); + } + String data = null; + JweEncryptionProvider theEncProvider = getInitializedEncryptionProvider(isJweRequired()); + if (isJwsRequired()) { + JwsJwtCompactProducer jws = new JwsJwtCompactProducer(jwt); + JwsSignatureProvider theSigProvider = getInitializedSignatureProvider(isJwsRequired()); + data = jws.signWith(theSigProvider); + if (theEncProvider != null) { + data = theEncProvider.encrypt(StringUtils.toBytesUTF8(data), null); + } + } else { + JweJwtCompactProducer jwe = new JweJwtCompactProducer(jwt); + data = jwe.encryptWith(theEncProvider); } return data; } - protected JwsSignatureProvider getInitializedSigProvider(boolean jwsRequired, boolean jweRequired) { - if (sigProvider != null) { - return sigProvider; - } - JwsSignatureProvider theSigProvider = JwsUtils.loadSignatureProvider(jwsRequired); - if (theSigProvider == null && jweRequired) { - return new NoneJwsSignatureProvider(); - } - throw new SecurityException(); + + public boolean isJwsRequired() { + return jwsRequired; } - protected JweEncryptionProvider getInitializedEncryptionProvider(boolean required) { - if (encryptionProvider != null) { - return encryptionProvider; - } - return JweUtils.loadEncryptionProvider(required); + + public void setJwsRequired(boolean jwsRequired) { + this.jwsRequired = jwsRequired; + } + + public boolean isJweRequired() { + return jweRequired; + } + + public void setJweRequired(boolean jweRequired) { + this.jweRequired = jweRequired; } } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java index 6a55854..077c500 100644 --- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java +++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java @@ -25,6 +25,9 @@ import org.apache.cxf.rs.security.jose.JoseHeaders; public class JwtToken { private JoseHeaders headers; private JwtClaims claims; + public JwtToken(JwtClaims claims) { + this(new JoseHeaders(), claims); + } public JwtToken(JoseHeaders headers, JwtClaims claims) { this.headers = headers; this.claims = claims; http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthJoseJwtProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthJoseJwtProducer.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthJoseJwtProducer.java new file mode 100644 index 0000000..ae27021 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthJoseJwtProducer.java @@ -0,0 +1,87 @@ +/** + * 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.oauth2.provider; + +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPublicKey; + +import javax.crypto.SecretKey; + +import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm; +import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm; +import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; +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; +import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtProducer; +import org.apache.cxf.rs.security.oauth2.common.Client; +import org.apache.cxf.rt.security.crypto.CryptoUtils; + +public abstract class AbstractOAuthJoseJwtProducer extends AbstractJoseJwtProducer { + private boolean encryptWithClientCertificates; + private boolean encryptWithClientSecret; + private boolean signWithClientSecret; + + protected JwsSignatureProvider getInitializedSigProvider(Client c, boolean required) { + if (signWithClientSecret) { + byte[] hmac = CryptoUtils.decodeSequence(c.getClientSecret()); + return JwsUtils.getHmacSignatureProvider(hmac, SignatureAlgorithm.HS256); + } + return super.getInitializedSignatureProvider(required); + } + protected JweEncryptionProvider getInitializedEncryptionProvider(Client c, boolean required) { + JweEncryptionProvider theEncryptionProvider = null; + if (encryptWithClientSecret) { + SecretKey key = CryptoUtils.decodeSecretKey(c.getClientSecret()); + theEncryptionProvider = JweUtils.getDirectKeyJweEncryption(key, ContentAlgorithm.A128GCM); + } else if (encryptWithClientCertificates) { + X509Certificate cert = + (X509Certificate)CryptoUtils.decodeCertificate(c.getApplicationCertificates().get(0)); + theEncryptionProvider = JweUtils.createJweEncryptionProvider((RSAPublicKey)cert.getPublicKey(), + KeyAlgorithm.RSA_OAEP, + ContentAlgorithm.A128GCM, + null); + } + if (theEncryptionProvider == null) { + theEncryptionProvider = super.getInitializedEncryptionProvider(required); + } + return theEncryptionProvider; + + } + + public void setEncryptWithClientCertificates(boolean encryptWithClientCertificates) { + if (encryptWithClientSecret) { + throw new SecurityException(); + } + this.encryptWithClientCertificates = encryptWithClientCertificates; + } + public void setEncryptWithClientSecret(boolean encryptWithClientSecret) { + if (signWithClientSecret || encryptWithClientCertificates) { + throw new SecurityException(); + } + this.encryptWithClientSecret = encryptWithClientSecret; + } + public void setSignWithClientSecret(boolean signWithClientSecret) { + if (encryptWithClientSecret) { + throw new SecurityException(); + } + this.signWithClientSecret = signWithClientSecret; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java index c0caa7c..668bf0c 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java @@ -25,7 +25,6 @@ import javax.ws.rs.core.MultivaluedMap; import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer; -import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator; @@ -48,8 +47,7 @@ public abstract class AbstactJwtAccessTokenValidator extends AbstractJoseJwtCons MultivaluedMap<String, String> extraProps) throws OAuthServiceException { ServerAccessToken at = dataProvider.getAccessToken(authSchemeData); - JwtToken token = super.getJwtToken(at.getTokenKey(), false); - validateToken(token); + super.getJwtToken(at.getTokenKey()); return new AccessTokenValidation(at); } @@ -57,7 +55,5 @@ public abstract class AbstactJwtAccessTokenValidator extends AbstractJoseJwtCons this.dataProvider = dataProvider; } - protected void validateToken(JwtToken jwt) { - - } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/AbstractJwsJweProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/AbstractJwsJweProducer.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/AbstractJwsJweProducer.java deleted file mode 100644 index d8c760a..0000000 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/AbstractJwsJweProducer.java +++ /dev/null @@ -1,99 +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.oidc.idp; - -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPublicKey; - -import javax.crypto.SecretKey; - -import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm; -import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -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; -import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rt.security.crypto.CryptoUtils; - -public abstract class AbstractJwsJweProducer { - private JwsSignatureProvider sigProvider; - private JweEncryptionProvider encryptionProvider; - private boolean encryptWithClientCertificates; - private boolean encryptWithClientSecret; - private boolean signWithClientSecret; - public void setSignatureProvider(JwsSignatureProvider signatureProvider) { - this.sigProvider = signatureProvider; - } - - protected JwsSignatureProvider getInitializedSigProvider(Client c, boolean required) { - if (sigProvider != null) { - return sigProvider; - } - - if (signWithClientSecret) { - byte[] hmac = CryptoUtils.decodeSequence(c.getClientSecret()); - return JwsUtils.getHmacSignatureProvider(hmac, SignatureAlgorithm.HS256); - } else { - return JwsUtils.loadSignatureProvider(required); - } - } - protected JweEncryptionProvider getInitializedEncryptionProvider(Client c, boolean required) { - if (encryptionProvider != null) { - return encryptionProvider; - } - JweEncryptionProvider theEncryptionProvider = null; - if (encryptWithClientSecret) { - SecretKey key = CryptoUtils.decodeSecretKey(c.getClientSecret()); - theEncryptionProvider = JweUtils.getDirectKeyJweEncryption(key, ContentAlgorithm.A128GCM); - } else if (encryptWithClientCertificates) { - X509Certificate cert = - (X509Certificate)CryptoUtils.decodeCertificate(c.getApplicationCertificates().get(0)); - theEncryptionProvider = JweUtils.createJweEncryptionProvider((RSAPublicKey)cert.getPublicKey(), - KeyAlgorithm.RSA_OAEP, - ContentAlgorithm.A128GCM, - null); - } - if (theEncryptionProvider == null) { - theEncryptionProvider = JweUtils.loadEncryptionProvider(required); - } - return theEncryptionProvider; - - } - - public void setEncryptWithClientCertificates(boolean encryptWithClientCertificates) { - if (encryptWithClientSecret) { - throw new SecurityException(); - } - this.encryptWithClientCertificates = encryptWithClientCertificates; - } - public void setEncryptWithClientSecret(boolean encryptWithClientSecret) { - if (signWithClientSecret || encryptWithClientCertificates) { - throw new SecurityException(); - } - this.encryptWithClientSecret = encryptWithClientSecret; - } - public void setSignWithClientSecret(boolean signWithClientSecret) { - if (encryptWithClientSecret) { - throw new SecurityException(); - } - this.signWithClientSecret = signWithClientSecret; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenCodeResponseFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenCodeResponseFilter.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenCodeResponseFilter.java index 3272b6b..15b2c8a 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenCodeResponseFilter.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenCodeResponseFilter.java @@ -18,17 +18,15 @@ */ package org.apache.cxf.rs.security.oidc.idp; -import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; -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.jwt.JwtToken; import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; +import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthJoseJwtProducer; import org.apache.cxf.rs.security.oauth2.provider.AccessTokenResponseFilter; import org.apache.cxf.rs.security.oidc.common.IdToken; import org.apache.cxf.rs.security.oidc.utils.OidcUtils; -public class IdTokenCodeResponseFilter extends AbstractJwsJweProducer implements AccessTokenResponseFilter { +public class IdTokenCodeResponseFilter extends AbstractOAuthJoseJwtProducer implements AccessTokenResponseFilter { private UserInfoProvider userInfoProvider; private String issuer; @Override @@ -38,15 +36,8 @@ public class IdTokenCodeResponseFilter extends AbstractJwsJweProducer implements token.setIssuer(issuer); token.setAudience(st.getClient().getClientId()); - JwsJwtCompactProducer producer = new JwsJwtCompactProducer(token); - JwsSignatureProvider theSigProvider = getInitializedSigProvider(st.getClient(), true); - String idToken = producer.signWith(theSigProvider); - - JweEncryptionProvider theEncryptionProvider = getInitializedEncryptionProvider(st.getClient(), false); - if (theEncryptionProvider != null) { - idToken = theEncryptionProvider.encrypt(StringUtils.toBytesUTF8(idToken), null); - } - ct.getParameters().put(OidcUtils.ID_TOKEN, idToken); + String responseEntity = super.processJwt(new JwtToken(token)); + ct.getParameters().put(OidcUtils.ID_TOKEN, responseEntity); } http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/UserInfoService.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/UserInfoService.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/UserInfoService.java index 7896678..97ab548 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/UserInfoService.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/UserInfoService.java @@ -24,18 +24,15 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.jaxrs.ext.MessageContext; -import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactProducer; -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.jwt.JwtToken; import org.apache.cxf.rs.security.oauth2.common.OAuthContext; +import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthJoseJwtProducer; import org.apache.cxf.rs.security.oauth2.utils.OAuthContextUtils; import org.apache.cxf.rs.security.oidc.common.UserInfo; @Path("/userinfo") -public class UserInfoService extends AbstractJwsJweProducer { +public class UserInfoService extends AbstractOAuthJoseJwtProducer { private UserInfoProvider userInfoProvider; private String issuer; @@ -51,21 +48,9 @@ public class UserInfoService extends AbstractJwsJweProducer { userInfo.setIssuer(issuer); } userInfo.setAudience(oauth.getClientId()); - Object responseEntity = userInfo; - - JwsJwtCompactProducer producer = new JwsJwtCompactProducer(userInfo); - JwsSignatureProvider theSigProvider = getInitializedSigProvider(null, false); - JweEncryptionProvider theEncryptionProvider = getInitializedEncryptionProvider(null, false); - if (theSigProvider != null) { - String userInfoString = producer.signWith(theSigProvider); - if (theEncryptionProvider != null) { - userInfoString = theEncryptionProvider.encrypt(StringUtils.toBytesUTF8(userInfoString), null); - } - responseEntity = userInfoString; - } else if (theEncryptionProvider != null) { - JweJwtCompactProducer jwe = new JweJwtCompactProducer(userInfo); - responseEntity = jwe.encryptWith(theEncryptionProvider); + if (super.isJwsRequired() || super.isJweRequired()) { + responseEntity = super.processJwt(new JwtToken(userInfo)); } return Response.ok(responseEntity).build(); http://git-wip-us.apache.org/repos/asf/cxf/blob/9fc3be7e/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 619bd10..0b271e8 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 @@ -44,7 +44,6 @@ public abstract class AbstractTokenValidator { private WebClient jwkSetClient; private boolean supportSelfIssuedProvider; private ConcurrentHashMap<String, JsonWebKey> keyMap = new ConcurrentHashMap<String, JsonWebKey>(); - protected JwtToken getJwtToken(String wrappedJwtToken, boolean jweOnly) { if (wrappedJwtToken == null) { throw new SecurityException("ID Token is missing"); @@ -59,7 +58,7 @@ public abstract class AbstractTokenValidator { JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken); JwtToken jwt = jwtConsumer.getJwtToken(); - JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(jwt); + JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(jwt); return validateToken(jwtConsumer, jwt, theSigVerifier); } @@ -102,7 +101,7 @@ public abstract class AbstractTokenValidator { this.jweDecryptor = jweDecryptor; } - public void setJweVerifier(JwsSignatureVerifier theJwsVerifier) { + public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { this.jwsVerifier = theJwsVerifier; } @@ -124,7 +123,7 @@ public abstract class AbstractTokenValidator { } return JweUtils.loadDecryptionProvider(jweOnly); } - protected JwsSignatureVerifier getInitializedSigVerifier(JwtToken jwt) { + protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) { if (jwsVerifier != null) { return jwsVerifier; } @@ -182,4 +181,6 @@ public abstract class AbstractTokenValidator { public void setSupportSelfIssuedProvider(boolean supportSelfIssuedProvider) { this.supportSelfIssuedProvider = supportSelfIssuedProvider; } + + }
