You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by me...@apache.org on 2022/04/12 12:23:26 UTC

[ranger] branch ranger-2.3 updated: RANGER-2704 : Support browser login using kerberized authentication.

This is an automated email from the ASF dual-hosted git repository.

mehul pushed a commit to branch ranger-2.3
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.3 by this push:
     new bcd501a8d RANGER-2704 : Support browser login using kerberized authentication.
bcd501a8d is described below

commit bcd501a8d88135e1917019463a47d2349e16a166
Author: Vishal Suvagia <vi...@apache.org>
AuthorDate: Mon Feb 28 19:06:55 2022 +0530

    RANGER-2704 : Support browser login using kerberized authentication.
    
    Issue:
    Need to support browser login using kerberos authentication.
    
    Changes:
    Added changes to enable Ranger Admin to support kerberos ticket based login.
    
    Testing:
    Veriried kerberos ticket authentication is working on a kerberized browser.
    
    Signed-off-by: Mehul Parikh <me...@apache.org>
---
 .../security/web/filter/RangerKrbFilter.java       | 18 ++++++--
 .../web/filter/RangerSSOAuthenticationFilter.java  | 49 ++++++++++++++++++++++
 .../conf.dist/ranger-admin-default-site.xml        |  4 ++
 3 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKrbFilter.java b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKrbFilter.java
index 223a991c7..801b0974a 100644
--- a/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKrbFilter.java
+++ b/security-admin/src/main/java/org/apache/ranger/security/web/filter/RangerKrbFilter.java
@@ -111,6 +111,8 @@ public class RangerKrbFilter implements Filter {
 
   static final String ALLOW_TRUSTED_PROXY = "ranger.authentication.allow.trustedproxy";
 
+  private static final String supportKerberosAuthForBrowserLoginConfig = "ranger.allow.kerberos.auth.login.browser";
+
   private String[] browserUserAgents;
 
   private Properties config;
@@ -121,6 +123,8 @@ public class RangerKrbFilter implements Filter {
   private String cookieDomain;
   private String cookiePath;
   private String cookieName;
+  private boolean isKerberosEnabled = false;
+  private boolean supportKerberosAuthForBrowserLogin = false;
 
   /**
    * <p>Initializes the authentication filter and signer secret provider.</p>
@@ -160,6 +164,8 @@ public class RangerKrbFilter implements Filter {
     cookieDomain = config.getProperty(COOKIE_DOMAIN, null);
     cookiePath = config.getProperty(COOKIE_PATH, null);
     cookieName = config.getProperty(RangerCommonConstants.PROP_COOKIE_NAME, RangerCommonConstants.DEFAULT_COOKIE_NAME);
+    isKerberosEnabled = (PropertiesUtil.getProperty("hadoop.security.authentication", "simple").equalsIgnoreCase("kerberos"));
+    supportKerberosAuthForBrowserLogin = PropertiesUtil.getBooleanProperty(supportKerberosAuthForBrowserLoginConfig, false);
   }
 
   protected void initializeAuthHandler(String authHandlerClassName, FilterConfig filterConfig)
@@ -504,6 +510,7 @@ public class RangerKrbFilter implements Filter {
       LOG.warn("Authentication exception: " + ex.getMessage(), ex);
     }
     if (unauthorizedResponse) {
+      String doAsUser = request.getParameter("doAs");
       if (!httpResponse.isCommitted()) {
         if (LOG.isDebugEnabled()) {
           LOG.debug("create auth cookie");
@@ -514,7 +521,7 @@ public class RangerKrbFilter implements Filter {
         // present.. reset to 403 if not found..
         if ((errCode == HttpServletResponse.SC_UNAUTHORIZED)
             && (!httpResponse.containsHeader(
-                KerberosAuthenticator.WWW_AUTHENTICATE))) {
+                KerberosAuthenticator.WWW_AUTHENTICATE) && !isKerberosEnabled && !supportKerberosAuthForBrowserLogin)) {
           errCode = HttpServletResponse.SC_FORBIDDEN;
         }
         if (authenticationEx == null) {
@@ -523,12 +530,17 @@ public class RangerKrbFilter implements Filter {
               agents = RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT;
             }
             parseBrowserUserAgents(agents);
-            String doAsUser = request.getParameter("doAs");
             if(isBrowser(httpRequest.getHeader(RangerCSRFPreventionFilter.HEADER_USER_AGENT)) &&
-                    (!allowTrustedProxy || (allowTrustedProxy && StringUtils.isEmpty(doAsUser))) ){
+                    (!allowTrustedProxy || (allowTrustedProxy && StringUtils.isEmpty(doAsUser))) && !supportKerberosAuthForBrowserLogin){
         	  ((HttpServletResponse)response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, "");
                 filterChain.doFilter(request, response);
             }else{
+              if (isKerberosEnabled && isBrowser(httpRequest.getHeader(RangerCSRFPreventionFilter.HEADER_USER_AGENT)) && supportKerberosAuthForBrowserLogin) {
+                if (LOG.isDebugEnabled()) {
+                  LOG.debug("Kerberos and ticket based browser login is enabled setting header to authenticate ticket based login for user.");
+                }
+                ((HttpServletResponse) response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
+              }
               if (allowTrustedProxy) {
                 String expectHeader = httpRequest.getHeader("Expect");
                 if (LOG.isDebugEnabled()) {
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 abbf2d983..63079d7ca 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
@@ -251,6 +251,32 @@ public class RangerSSOAuthenticationFilter implements Filter {
 				url = url.replace(RestUtil.LOCAL_LOGIN_URL, "");
 				LOG.warn("There is an active session and if you want local login to ranger, try this on a separate browser");
 				((HttpServletResponse)servletResponse).sendRedirect(url);
+        } else if (!ssoEnabled && ((HttpServletRequest) servletRequest).getRequestURI().contains(RestUtil.LOCAL_LOGIN_URL) && !isAuthenticated() &&
+				( isWebUserAgent(userAgent) || isBrowserAgent(userAgent))) {
+			// if sso is not enabled and request has locallogin then need to redirect user to the login page.
+			String url = ((HttpServletRequest) servletRequest).getRequestURI().replace(RestUtil.LOCAL_LOGIN_URL+"/", "");
+			url = url.replace(RestUtil.LOCAL_LOGIN_URL, "login.jsp");
+			// invalidating session
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("Request does not have any authentication and contains local login url redirecting to login page.");
+			}
+			((HttpServletRequest) servletRequest).getSession().invalidate();
+
+			((HttpServletResponse)servletResponse).sendRedirect(url);
+		} else if (!ssoEnabled && !((HttpServletRequest) servletRequest).getRequestURI().contains(RestUtil.LOCAL_LOGIN_URL) && !isAuthenticated() &&
+				( isWebUserAgent(userAgent) || isBrowserAgent(userAgent)) && !isKerberosAuthEnabled()) {
+			// if sso is not enabled and request has is from browser and user is not authenticated and browser kerberos auth is not enabled
+			// then need to redirect user to the login page.
+			String url = ((HttpServletRequest) servletRequest).getRequestURI() ;
+			if (!url.contains("login.jsp")) {
+				url = url + "login.jsp";
+			}
+			// invalidating session
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("Request does not have any authentication, redirecting to login page.");
+			}
+			((HttpServletRequest) servletRequest).getSession().invalidate();
+			((HttpServletResponse)servletResponse).sendRedirect(url);
 		}
 		//if sso is not enable or the request is not from browser then proceed further with next filter
 		else {
@@ -576,4 +602,27 @@ public class RangerSSOAuthenticationFilter implements Filter {
                 }
                 return loginURL;
         }
+
+
+    protected boolean isBrowserAgent(String userAgent) {
+        boolean isWeb = false;
+        String agents = PropertiesUtil.getProperty("ranger.krb.browser-useragents-regex", RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT);
+        if (agents == null) {
+            agents = RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT;
+        }
+        String[] browserUserAgents = agents.split(",");
+        if (browserUserAgents.length > 0 && userAgent != null) {
+            for (String ua : browserUserAgents) {
+                if (userAgent.toLowerCase().startsWith(ua.toLowerCase())) {
+                    isWeb = true;
+                    break;
+                }
+            }
+        }
+        return isWeb;
+    }
+
+	protected boolean isKerberosAuthEnabled() {
+		return PropertiesUtil.getBooleanProperty("ranger.allow.kerberos.auth.login.browser", false);
+	}
 }
diff --git a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
index f95b802fb..e8544c681 100644
--- a/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
+++ b/security-admin/src/main/resources/conf.dist/ranger-admin-default-site.xml
@@ -636,4 +636,8 @@
             <name>ranger.tomcat.work.dir</name>
             <value></value>
           </property>
+	<property>
+		<name>ranger.allow.kerberos.auth.login.browser</name>
+		<value>false</value>
+	</property>
 </configuration>