Repository: cxf Updated Branches: refs/heads/master 3fb5e2464 -> dd76961dc
Making sure OIDC RP validation errors can be caught by OAuthServiceException mappers, a specialized exception subclass might need to be introduced Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/dd76961d Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/dd76961d Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/dd76961d Branch: refs/heads/master Commit: dd76961dcd50dfb07dd95d37ecf9a2f457db18bf Parents: 3fb5e24 Author: Sergey Beryozkin <sberyoz...@gmail.com> Authored: Tue Dec 15 17:43:58 2015 +0000 Committer: Sergey Beryozkin <sberyoz...@gmail.com> Committed: Tue Dec 15 17:43:58 2015 +0000 ---------------------------------------------------------------------- .../oidc/rp/AbstractTokenValidator.java | 34 ++++++++++++++------ .../cxf/rs/security/oidc/rp/UserInfoClient.java | 3 +- .../cxf/rs/security/oidc/utils/OidcUtils.java | 5 +-- 3 files changed, 30 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/dd76961d/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 0db3541..9e305e3 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 @@ -29,9 +29,11 @@ import org.apache.cxf.rs.security.jose.jwk.JwkUtils; 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.JwtException; import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.cxf.rs.security.jose.jwt.JwtUtils; import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthJoseJwtConsumer; +import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; public abstract class AbstractTokenValidator extends AbstractOAuthJoseJwtConsumer { private static final String SELF_ISSUED_ISSUER = "https://self-issued.me"; @@ -54,44 +56,58 @@ public abstract class AbstractTokenValidator extends AbstractOAuthJoseJwtConsume // validate the issuer String issuer = claims.getIssuer(); if (issuer == null && validateClaimsAlways) { - throw new SecurityException("Invalid provider"); + throw new OAuthServiceException("Invalid issuer"); } if (supportSelfIssuedProvider && issuerId == null && issuer != null && SELF_ISSUED_ISSUER.equals(issuer)) { - //TODO: self-issued provider token validation + validateSelfIssuedProvider(claims, clientId, validateClaimsAlways); } else { if (issuer != null && !issuer.equals(issuerId)) { - throw new SecurityException("Invalid provider"); + throw new OAuthServiceException("Invalid issuer"); } // validate subject if (claims.getSubject() == null) { - throw new SecurityException("Invalid subject"); + throw new OAuthServiceException("Invalid subject"); } // validate audience List<String> audiences = claims.getAudiences(); if (StringUtils.isEmpty(audiences) && validateClaimsAlways || !StringUtils.isEmpty(audiences) && !audiences.contains(clientId)) { - throw new SecurityException("Invalid audience"); + throw new OAuthServiceException("Invalid audience"); } // If strict time validation: if no issuedTime claim is set then an expiresAt claim must be set // Otherwise: validate only if expiresAt claim is set boolean expiredRequired = validateClaimsAlways || strictTimeValidation && claims.getIssuedAt() == null; - JwtUtils.validateJwtExpiry(claims, clockOffset, expiredRequired); + try { + JwtUtils.validateJwtExpiry(claims, clockOffset, expiredRequired); + } catch (JwtException ex) { + throw new OAuthServiceException("ID Token has expired", ex); + } // If strict time validation: If no expiresAt claim is set then an issuedAt claim must be set // Otherwise: validate only if issuedAt claim is set boolean issuedAtRequired = validateClaimsAlways || strictTimeValidation && claims.getExpiryTime() == null; - JwtUtils.validateJwtIssuedAt(claims, ttl, clockOffset, issuedAtRequired); - + try { + JwtUtils.validateJwtIssuedAt(claims, ttl, clockOffset, issuedAtRequired); + } catch (JwtException ex) { + throw new OAuthServiceException("Invalid issuedAt claim", ex); + } if (strictTimeValidation) { - JwtUtils.validateJwtNotBefore(claims, clockOffset, strictTimeValidation); + try { + JwtUtils.validateJwtNotBefore(claims, clockOffset, strictTimeValidation); + } catch (JwtException ex) { + throw new OAuthServiceException("ID Token can not be used yet", ex); + } } } } + private void validateSelfIssuedProvider(JwtClaims claims, String clientId, boolean validateClaimsAlways) { + } + public void setIssuerId(String issuerId) { this.issuerId = issuerId; } http://git-wip-us.apache.org/repos/asf/cxf/blob/dd76961d/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 a052d0a..2c1f6ca 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 @@ -25,6 +25,7 @@ import org.apache.cxf.rs.security.jose.jwt.JwtToken; import org.apache.cxf.rs.security.oauth2.client.Consumer; import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils; import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken; +import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; import org.apache.cxf.rs.security.oidc.common.IdToken; import org.apache.cxf.rs.security.oidc.common.UserInfo; @@ -73,7 +74,7 @@ public class UserInfoClient extends AbstractTokenValidator { validateJwtClaims(profile, client.getClientId(), false); // validate subject if (!idToken.getSubject().equals(profile.getSubject())) { - throw new SecurityException("Invalid subject"); + throw new OAuthServiceException("Invalid subject"); } } public void setUserInfoServiceClient(WebClient client) { http://git-wip-us.apache.org/repos/asf/cxf/blob/dd76961d/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java index 19534f5..d6363e7 100644 --- a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java +++ b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/utils/OidcUtils.java @@ -30,6 +30,7 @@ import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; import org.apache.cxf.rs.security.jose.jws.JwsException; 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.provider.OAuthServiceException; import org.apache.cxf.rs.security.oidc.common.IdToken; import org.apache.cxf.rs.security.oidc.common.UserInfo; import org.apache.cxf.rt.security.crypto.MessageDigestUtils; @@ -114,7 +115,7 @@ public final class OidcUtils { private static void validateHash(String value, String theHash, SignatureAlgorithm joseAlgo) { String hash = calculateHash(value, joseAlgo); if (!hash.equals(theHash)) { - throw new SecurityException("Invalid hash"); + throw new OAuthServiceException("Invalid hash"); } } public static String calculateAccessTokenHash(String value, SignatureAlgorithm sigAlgo) { @@ -136,7 +137,7 @@ public final class OidcUtils { byte[] digest = MessageDigestUtils.createDigest(atBytes, javaShaAlgo); return Base64UrlUtility.encodeChunk(digest, 0, valueHashSize); } catch (NoSuchAlgorithmException ex) { - throw new SecurityException(ex); + throw new OAuthServiceException(ex); } }