You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ta...@apache.org on 2019/08/28 05:28:47 UTC

[hadoop] branch trunk updated: HADOOP-16527. Add a whitelist of endpoints to skip Kerberos authentication (#1336) Contributed by Akira Ajisaka.

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

tasanuma pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 55cc115  HADOOP-16527. Add a whitelist of endpoints to skip Kerberos authentication (#1336) Contributed by Akira Ajisaka.
55cc115 is described below

commit 55cc115878d029869be3e622e8792c9ad9f64982
Author: Akira Ajisaka <aa...@apache.org>
AuthorDate: Wed Aug 28 14:28:41 2019 +0900

    HADOOP-16527. Add a whitelist of endpoints to skip Kerberos authentication (#1336) Contributed by Akira Ajisaka.
---
 .../server/KerberosAuthenticationHandler.java      | 37 ++++++++++++++++++++++
 .../server/TestKerberosAuthenticationHandler.java  | 24 ++++++++++++++
 .../src/main/resources/core-default.xml            | 13 ++++++++
 3 files changed, 74 insertions(+)

diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java
index 7a918b2..50eeb2a 100644
--- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java
@@ -13,6 +13,7 @@
  */
 package org.apache.hadoop.security.authentication.server;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.hadoop.security.authentication.client.AuthenticationException;
 import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
 import org.apache.commons.codec.binary.Base64;
@@ -38,6 +39,8 @@ import java.io.IOException;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Properties;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -94,10 +97,18 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
    */
   public static final String RULE_MECHANISM = TYPE + ".name.rules.mechanism";
 
+  /**
+   * Constant for the list of endpoints that skips Kerberos authentication.
+   */
+  @VisibleForTesting
+  static final String ENDPOINT_WHITELIST = TYPE + ".endpoint.whitelist";
+  private static final Pattern ENDPOINT_PATTERN = Pattern.compile("^/[\\w]+");
+
   private String type;
   private String keytab;
   private GSSManager gssManager;
   private Subject serverSubject = new Subject();
+  private final Collection<String> whitelist = new HashSet<>();
 
   /**
    * Creates a Kerberos SPNEGO authentication handler with the default
@@ -173,6 +184,22 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
       if (ruleMechanism != null) {
         KerberosName.setRuleMechanism(ruleMechanism);
       }
+
+      final String whitelistStr = config.getProperty(ENDPOINT_WHITELIST, null);
+      if (whitelistStr != null) {
+        final String[] strs = whitelistStr.trim().split("\\s*[,\n]\\s*");
+        for (String s: strs) {
+          if (s.isEmpty()) continue;
+          if (ENDPOINT_PATTERN.matcher(s).matches()) {
+            whitelist.add(s);
+          } else {
+            throw new ServletException(
+                "The element of the whitelist: " + s + " must start with '/'"
+                    + " and must not contain special characters afterwards");
+          }
+        }
+      }
+
       try {
         gssManager = Subject.doAs(serverSubject,
             new PrivilegedExceptionAction<GSSManager>() {
@@ -269,6 +296,16 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
   public AuthenticationToken authenticate(HttpServletRequest request,
       final HttpServletResponse response)
       throws IOException, AuthenticationException {
+
+    // If the request servlet path is in the whitelist,
+    // skip Kerberos authentication and return anonymous token.
+    final String path = request.getServletPath();
+    for(final String endpoint: whitelist) {
+      if (endpoint.equals(path)) {
+        return AuthenticationToken.ANONYMOUS;
+      }
+    }
+
     AuthenticationToken token = null;
     String authorization = request.getHeader(
         KerberosAuthenticator.AUTHORIZATION);
diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestKerberosAuthenticationHandler.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestKerberosAuthenticationHandler.java
index bef3018..629b68b 100644
--- a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestKerberosAuthenticationHandler.java
+++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestKerberosAuthenticationHandler.java
@@ -89,6 +89,9 @@ public class TestKerberosAuthenticationHandler
     // handler
     handler = getNewAuthenticationHandler();
     Properties props = getDefaultProperties();
+    // Set whitelist for testing
+    props.setProperty(KerberosAuthenticationHandler.ENDPOINT_WHITELIST,
+        "/white,/white2,/white3");
     try {
       handler.init(props);
     } catch (Exception ex) {
@@ -371,6 +374,27 @@ public class TestKerberosAuthenticationHandler
     }
   }
 
+  @Test
+  public void testRequestToWhitelist() throws Exception {
+    final String token = new Base64(0).encodeToString(new byte[]{0, 1, 2});
+    final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    final HttpServletResponse response =
+        Mockito.mock(HttpServletResponse.class);
+    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION))
+        .thenReturn(KerberosAuthenticator.NEGOTIATE + token);
+    Mockito.when(request.getServletPath()).thenReturn("/white");
+    handler.authenticate(request, response);
+    Mockito.when(request.getServletPath()).thenReturn("/white4");
+    try {
+      handler.authenticate(request, response);
+      Assert.fail();
+    } catch (AuthenticationException ex) {
+      // Expected
+    } catch (Exception ex) {
+      Assert.fail();
+    }
+  }
+
   @After
   public void tearDown() throws Exception {
     if (handler != null) {
diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
index 2b78ede..7ed3e8a 100644
--- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
+++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
@@ -2495,6 +2495,19 @@
   </description>
 </property>
 
+  <property>
+    <name>hadoop.http.authentication.kerberos.endpoint.whitelist</name>
+    <value></value>
+    <description>
+      The comma-separated list of the endpoints that skips Kerberos
+      authentication. The endpoint must start with '/' and must not
+      contain special characters afterwards. This parameter is for
+      the monitoring tools that do not support Kerberos authentication.
+      Administrator must configure this parameter very carefully
+      because it allows unauthenticated access to the daemons.
+    </description>
+  </property>
+
 <!-- HTTP CORS support -->
 <property>
   <name>hadoop.http.cross-origin.enabled</name>


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org