Repository: ranger
Updated Branches:
  refs/heads/ranger-0.7 216704aea -> ad9ae7656


RANGER-2049: Added support for doAs for Ranger REST APIs with Kerberized mode


Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/39df85e7
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/39df85e7
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/39df85e7

Branch: refs/heads/ranger-0.7
Commit: 39df85e72d6037ee80180719b1df84c8f9fdca4d
Parents: 216704a
Author: Sailaja Polavarapu <[email protected]>
Authored: Tue Nov 13 16:22:01 2018 -0800
Committer: Sailaja Polavarapu <[email protected]>
Committed: Tue Dec 4 16:36:27 2018 -0800

----------------------------------------------------------------------
 .../filter/RangerKRBAuthenticationFilter.java   | 132 +++++++++++++++----
 1 file changed, 105 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/39df85e7/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKRBAuthenticationFilter.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKRBAuthenticationFilter.java
 
b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKRBAuthenticationFilter.java
index 11bc9e2..519071e 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKRBAuthenticationFilter.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKRBAuthenticationFilter.java
@@ -32,6 +32,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Collections;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -53,6 +54,13 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.collections.iterators.IteratorEnumeration;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.SaslRpcServer;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.server.AuthenticationToken;
+import org.apache.hadoop.security.authorize.AuthorizationException;
+import org.apache.hadoop.security.authorize.ProxyUsers;
+import org.apache.hadoop.util.HttpExceptionUtils;
 import org.apache.ranger.biz.UserMgr;
 import org.apache.ranger.common.PropertiesUtil;
 import org.apache.ranger.common.RESTErrorUtil;
@@ -98,6 +106,8 @@ public class RangerKRBAuthenticationFilter extends 
RangerKrbFilter {
        static final String RANGER_AUTH_TYPE = "hadoop.security.authentication";
        static final String AUTH_COOKIE_NAME = "hadoop.auth";
        static final String HOST_NAME = "ranger.service.host";
+       static final String ALLOW_TRUSTED_PROXY = 
"ranger.authentication.allow.trustedproxy";
+       static final String PROXY_PREFIX = "ranger.proxyuser.";
 
        private static final String KERBEROS_TYPE = "kerberos";
        private static final String S_USER = "suser";
@@ -119,6 +129,7 @@ public class RangerKRBAuthenticationFilter extends 
RangerKrbFilter {
                params.put(TOKEN_VALID_PARAM, 
PropertiesUtil.getProperty(TOKEN_VALID,"30"));
                params.put(COOKIE_DOMAIN_PARAM, 
PropertiesUtil.getProperty(COOKIE_DOMAIN, PropertiesUtil.getProperty(HOST_NAME, 
"localhost")));
                params.put(COOKIE_PATH_PARAM, 
PropertiesUtil.getProperty(COOKIE_PATH, "/"));
+               params.put(ALLOW_TRUSTED_PROXY, 
PropertiesUtil.getProperty(ALLOW_TRUSTED_PROXY, "false"));
                try {
                        params.put(PRINCIPAL_PARAM, 
SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(PRINCIPAL,""), 
PropertiesUtil.getProperty(HOST_NAME)));
                } catch (IOException ignored) {
@@ -153,6 +164,20 @@ public class RangerKRBAuthenticationFilter extends 
RangerKrbFilter {
                        }
                };
                super.init(myConf);
+               Configuration conf1 = this.getProxyuserConfiguration();
+               ProxyUsers.refreshSuperUserGroupsConfiguration(conf1, 
PROXY_PREFIX);
+       }
+
+       protected Configuration getProxyuserConfiguration() {
+               Configuration conf = new Configuration(false);
+               Map<String, String> propertiesMap = 
PropertiesUtil.getPropertiesMap();
+               for (String key : propertiesMap.keySet()) {
+                       if (!key.startsWith(PROXY_PREFIX)) {
+                               continue;
+                       }
+                       conf.set(key, propertiesMap.get(key));
+               }
+               return conf;
        }
 
        @Override
@@ -162,6 +187,7 @@ public class RangerKRBAuthenticationFilter extends 
RangerKrbFilter {
                String authType = PropertiesUtil.getProperty(RANGER_AUTH_TYPE);
                String userName = null;
                boolean checkCookie = response.containsHeader("Set-Cookie");
+               boolean allowTrustedProxy = 
PropertiesUtil.getBooleanProperty(ALLOW_TRUSTED_PROXY, false);
                if(checkCookie){
                        Collection<String> authUserName = 
response.getHeaders("Set-Cookie");
                        if(authUserName != null){
@@ -200,46 +226,98 @@ public class RangerKRBAuthenticationFilter extends 
RangerKrbFilter {
                        userName = sessionUserName;
                }
 
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("Remote user from request = " + 
request.getRemoteUser());
+               }
+
                if((isSpnegoEnable(authType) && 
(!StringUtils.isEmpty(userName)))){
                        Authentication existingAuth = 
SecurityContextHolder.getContext().getAuthentication();
                        if(existingAuth == null || 
!existingAuth.isAuthenticated()){
                                //--------------------------- To Create Ranger 
Session --------------------------------------
                                String rangerLdapDefaultRole = 
PropertiesUtil.getProperty("ranger.ldap.default.role", "ROLE_USER");
-                               //if we get the userName from the token then 
log into ranger using the same user
-                               final List<GrantedAuthority> grantedAuths = new 
ArrayList<>();
-                               grantedAuths.add(new 
SimpleGrantedAuthority(rangerLdapDefaultRole));
-                               final UserDetails principal = new 
User(userName, "",grantedAuths);
-                               final Authentication finalAuthentication = new 
UsernamePasswordAuthenticationToken(principal, "", grantedAuths);
-                               WebAuthenticationDetails webDetails = new 
WebAuthenticationDetails(request);
-                               ((AbstractAuthenticationToken) 
finalAuthentication).setDetails(webDetails);
-                               RangerAuthenticationProvider 
authenticationProvider = new RangerAuthenticationProvider();
-                               Authentication authentication = 
authenticationProvider.authenticate(finalAuthentication);
-                               authentication = 
getGrantedAuthority(authentication);
-                               if(authentication != null && 
authentication.isAuthenticated()) {
-                                       if 
(request.getParameterMap().containsKey("doAs")) {
-                                               if(!response.isCommitted()) {
+                               if(LOG.isDebugEnabled()) {
+                                       LOG.debug("Http headers: " + 
Collections.list(request.getHeaderNames()).toString());
+                               }
+                               String doAsUser = request.getParameter("doAs");
+
+                               if (allowTrustedProxy && doAsUser != null && 
!doAsUser.isEmpty()) {
+                                       if(LOG.isDebugEnabled()) {
+                                               LOG.debug("userPrincipal from 
request = " + request.getUserPrincipal() + " request paramerters = " + 
request.getParameterMap().keySet());
+                                       }
+                                       AuthenticationToken authToken = 
(AuthenticationToken)request.getUserPrincipal();
+                                       if(authToken != null && authToken != 
AuthenticationToken.ANONYMOUS) {
+                                               if(LOG.isDebugEnabled()) {
+                                                       LOG.debug("remote user 
from authtoken = " + authToken.getUserName());
+                                               }
+                                               UserGroupInformation ugi = 
UserGroupInformation.createRemoteUser(authToken.getUserName(), 
SaslRpcServer.AuthMethod.KERBEROS);
+                                               if(ugi != null) {
+                                                       ugi = 
UserGroupInformation.createProxyUser(doAsUser, ugi);
                                                        
if(LOG.isDebugEnabled()) {
-                                                               
LOG.debug("Request contains unsupported parameter, doAs.");
+                                                               LOG.debug("Real 
user from UGI = " + ugi.getRealUser().getShortUserName());
+                                                       }
+
+                                                       try {
+                                                               
ProxyUsers.authorize(ugi, request.getRemoteAddr());
+                                                       } catch 
(AuthorizationException ex) {
+                                                               
HttpExceptionUtils.createServletExceptionResponse(response, 403, ex);
+                                                               
if(LOG.isDebugEnabled()) {
+                                                                       
LOG.debug("Authentication exception: " + ex.getMessage(), ex);
+                                                               } else {
+                                                                       
LOG.warn("Authentication exception: " + ex.getMessage());
+                                                               }
+                                                               return;
                                                        }
-                                                       
request.setAttribute("spnegoenabled", false);
-                                                       
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Missing authentication 
token.");
+                                                       final 
List<GrantedAuthority> grantedAuths = new ArrayList<>();
+                                                       grantedAuths.add(new 
SimpleGrantedAuthority(rangerLdapDefaultRole));
+                                                       final UserDetails 
principal = new User(doAsUser, "", grantedAuths);
+                                                       final Authentication 
finalAuthentication = new UsernamePasswordAuthenticationToken(principal, "", 
grantedAuths);
+                                                       
WebAuthenticationDetails webDetails = new WebAuthenticationDetails(request);
+                                                       
((AbstractAuthenticationToken) finalAuthentication).setDetails(webDetails);
+                                                       
SecurityContextHolder.getContext().setAuthentication(finalAuthentication);
+                                                       
request.setAttribute("spnegoEnabled", true);
                                                }
+
                                        }
-                                       
if(request.getParameterMap().containsKey("user.name")) {
-                                               if(!response.isCommitted()) {
-                                                       
if(LOG.isDebugEnabled()) {
-                                                               
LOG.debug("Request contains an unsupported parameter user.name");
+                                       LOG.info("Logged into Ranger as 
doAsUser = " + doAsUser + ", by authenticatedUser=" + authToken.getUserName());
+
+
+                               }else {
+                                       //if we get the userName from the token 
then log into ranger using the same user
+                                       final List<GrantedAuthority> 
grantedAuths = new ArrayList<>();
+                                       grantedAuths.add(new 
SimpleGrantedAuthority(rangerLdapDefaultRole));
+                                       final UserDetails principal = new 
User(userName, "", grantedAuths);
+                                       final Authentication 
finalAuthentication = new UsernamePasswordAuthenticationToken(principal, "", 
grantedAuths);
+                                       WebAuthenticationDetails webDetails = 
new WebAuthenticationDetails(request);
+                                       ((AbstractAuthenticationToken) 
finalAuthentication).setDetails(webDetails);
+                                       RangerAuthenticationProvider 
authenticationProvider = new RangerAuthenticationProvider();
+                                       Authentication authentication = 
authenticationProvider.authenticate(finalAuthentication);
+                                       authentication = 
getGrantedAuthority(authentication);
+                                       if (authentication != null && 
authentication.isAuthenticated()) {
+                                               if 
(request.getParameterMap().containsKey("doAs")) {
+                                                       if 
(!response.isCommitted()) {
+                                                               if 
(LOG.isDebugEnabled()) {
+                                                                       
LOG.debug("Request contains unsupported parameter, doAs.");
+                                                               }
+                                                               
request.setAttribute("spnegoenabled", false);
+                                                               
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Missing authentication 
token.");
+                                                       }
+                                               }
+                                               if 
(request.getParameterMap().containsKey("user.name")) {
+                                                       if 
(!response.isCommitted()) {
+                                                               if 
(LOG.isDebugEnabled()) {
+                                                                       
LOG.debug("Request contains an unsupported parameter user.name");
+                                                               }
+                                                               
request.setAttribute("spnegoenabled", false);
+                                                               
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Missing authentication 
token.");
+                                                       } else {
+                                                               
LOG.info("Response seems to be already committed for user.name.");
                                                        }
-                                                       
request.setAttribute("spnegoenabled", false);
-                                                       
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Missing authentication 
token.");
-                                               } else {
-                                                       LOG.info("Response 
seems to be already committed for user.name.");
                                                }
                                        }
+                                       
SecurityContextHolder.getContext().setAuthentication(authentication);
+                                       request.setAttribute("spnegoEnabled", 
true);
+                                       LOG.info("Logged into Ranger as = " + 
userName);
                                }
-                               
SecurityContextHolder.getContext().setAuthentication(authentication);
-                               request.setAttribute("spnegoEnabled", true);
-                               LOG.info("Logged into Ranger as = "+userName);
                                filterChain.doFilter(request, response);
                        }else{
                                try{

Reply via email to