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 <vishalsuva...@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>

Reply via email to