Repository: ranger Updated Branches: refs/heads/master c3fbdae9f -> c61f97a3d
RANGER-1839 - Add the ability to specify SSO token audiences Project: http://git-wip-us.apache.org/repos/asf/ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/c61f97a3 Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/c61f97a3 Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/c61f97a3 Branch: refs/heads/master Commit: c61f97a3d22c12c7817b0c441a2ba78b5465b3ee Parents: c3fbdae Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Mon Oct 16 15:33:25 2017 +0100 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Tue Oct 17 10:33:26 2017 +0100 ---------------------------------------------------------------------- .../filter/RangerSSOAuthenticationFilter.java | 46 +++++++- .../web/filter/SSOAuthenticationProperties.java | 113 ++++++++++--------- 2 files changed, 107 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ranger/blob/c61f97a3/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSSOAuthenticationFilter.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSSOAuthenticationFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSSOAuthenticationFilter.java index 7cfe0be..5e4207c 100644 --- a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSSOAuthenticationFilter.java +++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerSSOAuthenticationFilter.java @@ -50,6 +50,7 @@ import java.security.cert.CertificateException; import java.security.interfaces.RSAPublicKey; import java.text.ParseException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Enumeration; @@ -75,6 +76,7 @@ public class RangerSSOAuthenticationFilter implements Filter { public static final String JWT_AUTH_PROVIDER_URL = "ranger.sso.providerurl"; public static final String JWT_PUBLIC_KEY = "ranger.sso.publicKey"; public static final String JWT_COOKIE_NAME = "ranger.sso.cookiename"; + public static final String JWT_AUDIENCES = "ranger.sso.audiences"; public static final String JWT_ORIGINAL_URL_QUERY_PARAM = "ranger.sso.query.param.originalurl"; public static final String JWT_COOKIE_NAME_DEFAULT = "hadoop-jwt"; public static final String JWT_ORIGINAL_URL_QUERY_PARAM_DEFAULT = "originalUrl"; @@ -382,12 +384,22 @@ public class RangerSSOAuthenticationFilter implements Filter { boolean sigValid = validateSignature(jwtToken); if (!sigValid) { LOG.warn("Signature of JWT token could not be verified. Please check the public key"); + return false; } + boolean expValid = validateExpiration(jwtToken); if (!expValid) { LOG.warn("Expiration time validation of JWT token failed."); + return false; } - return sigValid && expValid; + + boolean audiencesValid = validateAudiences(jwtToken); + if (!audiencesValid) { + LOG.warn("Audience validation of JWT token failed."); + return false; + } + + return true; } /** @@ -457,6 +469,34 @@ public class RangerSSOAuthenticationFilter implements Filter { return valid; } + protected boolean validateAudiences(SignedJWT jwtToken) { + boolean valid = false; + + if (jwtProperties.getAudiences().isEmpty()) { + // if there were no expected audiences configured then just + // consider any audience acceptable + valid = true; + } else { + try { + List<String> tokenAudienceList = jwtToken.getJWTClaimsSet().getAudience(); + // if any of the configured audiences is found then consider it acceptable + if (tokenAudienceList != null) { + for (String aud : tokenAudienceList) { + if (jwtProperties.getAudiences().contains(aud)) { + LOG.debug("Audience claim has been validated."); + valid = true; + break; + } + } + } + } catch (ParseException pe) { + LOG.warn("Audience validation failed.", pe); + } + } + + return valid; + } + @Override public void destroy() { } @@ -481,6 +521,10 @@ public class RangerSSOAuthenticationFilter implements Filter { userAgent = defaultUserAgent; jwtProperties.setUserAgentList(userAgent.split(",")); } + String audiences = PropertiesUtil.getProperty(JWT_AUDIENCES); + if (audiences != null && !audiences.isEmpty()) { + jwtProperties.setAudiences(Arrays.asList(audiences.split(","))); + } try { RSAPublicKey publicKey = parseRSAPublicKey(publicKeyPath); jwtProperties.setPublicKey(publicKey); http://git-wip-us.apache.org/repos/asf/ranger/blob/c61f97a3/security-admin/src/main/java/org/apache/ranger/security/web/filter/SSOAuthenticationProperties.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/SSOAuthenticationProperties.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/SSOAuthenticationProperties.java index 7706d9b..b8246a9 100644 --- a/security-admin/src/main/java/org/apache/ranger/security/web/filter/SSOAuthenticationProperties.java +++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/SSOAuthenticationProperties.java @@ -20,59 +20,70 @@ package org.apache.ranger.security.web.filter; import java.security.interfaces.RSAPublicKey; +import java.util.Collections; +import java.util.List; public class SSOAuthenticationProperties { - private String authenticationProviderUrl = null; - private RSAPublicKey publicKey = null; - private String cookieName = "hadoop-jwt"; - private String originalUrlQueryParam = null; - private String[] userAgentList = null; - - public String getAuthenticationProviderUrl() { - return authenticationProviderUrl; - } - - public void setAuthenticationProviderUrl(String authenticationProviderUrl) { - this.authenticationProviderUrl = authenticationProviderUrl; - } - - public RSAPublicKey getPublicKey() { - return publicKey; - } - - public void setPublicKey(RSAPublicKey publicKey) { - this.publicKey = publicKey; - } - - public String getCookieName() { - return cookieName; - } - - public void setCookieName(String cookieName) { - this.cookieName = cookieName; - } - - public String getOriginalUrlQueryParam() { - return originalUrlQueryParam; - } - - public void setOriginalUrlQueryParam(String originalUrlQueryParam) { - this.originalUrlQueryParam = originalUrlQueryParam; - } - - /** - * @return the userAgentList - */ - public String[] getUserAgentList() { - return userAgentList; - } - - /** - * @param userAgentList the userAgentList to set - */ - public void setUserAgentList(String[] userAgentList) { - this.userAgentList = userAgentList; - } + private String authenticationProviderUrl; + private RSAPublicKey publicKey; + private String cookieName = "hadoop-jwt"; + private String originalUrlQueryParam; + private String[] userAgentList; + private List<String> audiences = Collections.emptyList(); + + public String getAuthenticationProviderUrl() { + return authenticationProviderUrl; + } + + public void setAuthenticationProviderUrl(String authenticationProviderUrl) { + this.authenticationProviderUrl = authenticationProviderUrl; + } + + public RSAPublicKey getPublicKey() { + return publicKey; + } + + public void setPublicKey(RSAPublicKey publicKey) { + this.publicKey = publicKey; + } + + public String getCookieName() { + return cookieName; + } + + public void setCookieName(String cookieName) { + this.cookieName = cookieName; + } + + public String getOriginalUrlQueryParam() { + return originalUrlQueryParam; + } + + public void setOriginalUrlQueryParam(String originalUrlQueryParam) { + this.originalUrlQueryParam = originalUrlQueryParam; + } + + /** + * @return the userAgentList + */ + public String[] getUserAgentList() { + return userAgentList; + } + + /** + * @param userAgentList the userAgentList to set + */ + public void setUserAgentList(String[] userAgentList) { + this.userAgentList = userAgentList; + } + + public List<String> getAudiences() { + return audiences; + } + + public void setAudiences(List<String> audiences) { + this.audiences = audiences; + } }