Repository: cxf Updated Branches: refs/heads/3.0.x-fixes 23789300f -> ac86049f4
More work on the 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/ac86049f Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/ac86049f Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/ac86049f Branch: refs/heads/3.0.x-fixes Commit: ac86049f4347c368b24c8b6e72b6f7564806e907 Parents: 2378930 Author: Sergey Beryozkin <[email protected]> Authored: Wed Jul 29 17:36:18 2015 +0300 Committer: Sergey Beryozkin <[email protected]> Committed: Wed Jul 29 17:38:22 2015 +0300 ---------------------------------------------------------------------- .../jose/jwt/AbstractJoseJwtConsumer.java | 9 ++- .../jose/jwt/AbstractJoseJwtProducer.java | 2 +- .../oidc/rp/AbstractTokenValidator.java | 74 +++----------------- .../cxf/rs/security/oidc/rp/IdTokenReader.java | 2 +- .../oidc/rp/OidcClientCodeRequestFilter.java | 7 +- .../cxf/rs/security/oidc/rp/UserInfoClient.java | 19 +++-- 6 files changed, 31 insertions(+), 82 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/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 fc00c81..0708cac 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 @@ -27,7 +27,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { private boolean jwsRequired = true; - private boolean jweRequired = true; + private boolean jweRequired; protected JwtToken getJwtToken(String wrappedJwtToken) { if (!isJwsRequired() && !isJweRequired()) { @@ -42,14 +42,17 @@ public abstract class AbstractJoseJwtConsumer extends AbstractJoseConsumer { } JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken); - JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(isJwsRequired()); + JwtToken jwt = jwtConsumer.getJwtToken(); + JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(jwt); if (!jwtConsumer.verifySignatureWith(theSigVerifier)) { throw new SecurityException("Invalid Signature"); } - JwtToken jwt = jwtConsumer.getJwtToken(); validateToken(jwt); return jwt; } + protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) { + return super.getInitializedSignatureVerifier(isJwsRequired()); + } protected void validateToken(JwtToken jwt) { } public boolean isJwsRequired() { http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/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 bd2e1da..6ec4b44 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 @@ -28,7 +28,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; public abstract class AbstractJoseJwtProducer extends AbstractJoseProducer { private boolean jwsRequired = true; - private boolean jweRequired = true; + private boolean jweRequired; protected String processJwt(JwtToken jwt) { if (!isJwsRequired() && !isJweRequired()) { http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/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 0b271e8..e79c4f0 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 @@ -21,48 +21,25 @@ package org.apache.cxf.rs.security.oidc.rp; 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.jwk.JwkUtils; -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.AbstractJoseJwtConsumer; 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 { +public abstract class AbstractTokenValidator extends AbstractJoseJwtConsumer { private static final String SELF_ISSUED_ISSUER = "https://self-issued.me"; - private JweDecryptionProvider jweDecryptor; - private JwsSignatureVerifier jwsVerifier; private String issuerId; private int issuedAtRange; private int clockOffset; 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"); - } - JweDecryptionProvider theJweDecryptor = getInitializedDecryptionProvider(jweOnly); - if (theJweDecryptor != null) { - if (jweOnly) { - return new JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor); - } - wrappedJwtToken = jweDecryptor.decrypt(wrappedJwtToken).getContentText(); - } - - JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(wrappedJwtToken); - JwtToken jwt = jwtConsumer.getJwtToken(); - JwsSignatureVerifier theSigVerifier = getInitializedSignatureVerifier(jwt); - return validateToken(jwtConsumer, jwt, theSigVerifier); - } - protected void validateJwtClaims(JwtClaims claims, String clientId, boolean validateClaimsAlways) { // validate the issuer String issuer = claims.getIssuer(); @@ -90,21 +67,6 @@ public abstract class AbstractTokenValidator { } } - - protected JwtToken validateToken(JwsJwtCompactConsumer consumer, JwtToken jwt, JwsSignatureVerifier jws) { - if (!consumer.verifySignatureWith(jws)) { - throw new SecurityException("Invalid Signature"); - } - return jwt; - } - public void setJweDecryptor(JweDecryptionProvider jweDecryptor) { - this.jweDecryptor = jweDecryptor; - } - - public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { - this.jwsVerifier = theJwsVerifier; - } - public void setIssuerId(String issuerId) { this.issuerId = issuerId; } @@ -117,21 +79,8 @@ public abstract class AbstractTokenValidator { this.issuedAtRange = issuedAtRange; } - protected JweDecryptionProvider getInitializedDecryptionProvider(boolean jweOnly) { - if (jweDecryptor != null) { - return jweDecryptor; - } - return JweUtils.loadDecryptionProvider(jweOnly); - } + @Override protected JwsSignatureVerifier getInitializedSignatureVerifier(JwtToken jwt) { - if (jwsVerifier != null) { - return jwsVerifier; - } - JwsSignatureVerifier theJwsVerifier = JwsUtils.loadSignatureVerifier(false); - if (theJwsVerifier != null) { - return theJwsVerifier; - } - JsonWebKey key = null; if (supportSelfIssuedProvider && SELF_ISSUED_ISSUER.equals(jwt.getClaim("issuer"))) { String publicKeyJson = (String)jwt.getClaim("sub_jwk"); @@ -148,10 +97,7 @@ public abstract class AbstractTokenValidator { } else { String keyId = jwt.getHeaders().getKeyId(); key = keyId != null ? keyMap.get(keyId) : null; - if (key == null) { - if (jwkSetClient == null) { - throw new SecurityException("Provider Jwk Set Client is not available"); - } + if (key == null && jwkSetClient != null) { JsonWebKeys keys = jwkSetClient.get(JsonWebKeys.class); if (keyId != null) { key = keys.getKey(keyId); @@ -160,13 +106,13 @@ public abstract class AbstractTokenValidator { } keyMap.putAll(keys.getKeyIdMap()); } - if (key == null) { - throw new SecurityException("JWK key with the key id: \"" + keyId + "\" is not available"); - } } - - theJwsVerifier = JwsUtils.getSignatureVerifier(key); - + JwsSignatureVerifier theJwsVerifier = null; + if (key != null) { + theJwsVerifier = JwsUtils.getSignatureVerifier(key); + } else { + theJwsVerifier = super.getInitializedSignatureVerifier(jwt); + } if (theJwsVerifier == null) { throw new SecurityException("JWS Verifier is not available"); } http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java index ff633a1..63161d5 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/IdTokenReader.java @@ -40,7 +40,7 @@ public class IdTokenReader extends AbstractTokenValidator { return jwt; } public JwtToken getIdJwtToken(String idJwtToken, String clientId) { - JwtToken jwt = getJwtToken(idJwtToken, false); + JwtToken jwt = getJwtToken(idJwtToken); validateJwtClaims(jwt.getClaims(), clientId, true); return jwt; } http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java index 6406e3b..aa34cf1 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java @@ -41,6 +41,7 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { private static final String MAX_AGE_PARAMETER = "max_age"; private static final List<String> PROMPTS = Arrays.asList("none", "consent", "login", "select_account"); private IdTokenReader idTokenReader; + private UserInfoClient userInfoClient; private List<String> authenticationContextRef; private String promptLogin; private Long maxAgeOffset; @@ -64,8 +65,7 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { validateIdToken(idToken, state); ctx.setIdToken(idToken); - if (idTokenReader instanceof UserInfoClient) { - UserInfoClient userInfoClient = (UserInfoClient)idTokenReader; + if (userInfoClient != null) { ctx.setUserInfo(userInfoClient.getUserInfo(at, ctx.getIdToken())); } rc.setSecurityContext(new OidcSecurityContext(ctx)); @@ -106,6 +106,9 @@ public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter { public void setIdTokenReader(IdTokenReader idTokenReader) { this.idTokenReader = idTokenReader; } + public void setUserInfoClient(UserInfoClient userInfoClient) { + this.userInfoClient = userInfoClient; + } @Override protected void checkSecurityContextStart(ContainerRequestContext rc) { http://git-wip-us.apache.org/repos/asf/cxf/blob/ac86049f/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java index f1d0998..058867c 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/UserInfoClient.java @@ -27,17 +27,14 @@ import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken; import org.apache.cxf.rs.security.oidc.common.IdToken; import org.apache.cxf.rs.security.oidc.common.UserInfo; -public class UserInfoClient extends IdTokenReader { - private boolean encryptedOnly; +public class UserInfoClient extends AbstractTokenValidator { private boolean sendTokenAsFormParameter; private WebClient profileClient; + private boolean getUserInfoFromJwt; public UserInfo getUserInfo(ClientAccessToken at, IdToken idToken) { - return getUserInfo(at, idToken, false); - } - public UserInfo getUserInfo(ClientAccessToken at, IdToken idToken, boolean asJwt) { if (!sendTokenAsFormParameter) { OAuthClientUtils.setAuthorizationHeader(profileClient, at); - if (asJwt) { + if (getUserInfoFromJwt) { String jwt = profileClient.get(String.class); return getUserInfoFromJwt(jwt, idToken); } else { @@ -47,7 +44,7 @@ public class UserInfoClient extends IdTokenReader { } } else { Form form = new Form().param("access_token", at.getTokenKey()); - if (asJwt) { + if (getUserInfoFromJwt) { String jwt = profileClient.form(form).readEntity(String.class); return getUserInfoFromJwt(jwt, idToken); } else { @@ -67,7 +64,7 @@ public class UserInfoClient extends IdTokenReader { return profile; } public JwtToken getUserInfoJwt(String profileJwtToken) { - return getJwtToken(profileJwtToken, encryptedOnly); + return getJwtToken(profileJwtToken); } public void validateUserInfo(UserInfo profile, IdToken idToken) { validateJwtClaims(profile, idToken.getAudience(), false); @@ -76,14 +73,14 @@ public class UserInfoClient extends IdTokenReader { throw new SecurityException("Invalid subject"); } } - public void setEncryptedOnly(boolean encryptedOnly) { - this.encryptedOnly = encryptedOnly; - } public void setUserInfoServiceClient(WebClient client) { this.profileClient = client; } public void setSendTokenAsFormParameter(boolean sendTokenAsFormParameter) { this.sendTokenAsFormParameter = sendTokenAsFormParameter; } + public void setGetUserInfoFromJwt(boolean getUserInfoFromJwt) { + this.getUserInfoFromJwt = getUserInfoFromJwt; + } }
