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

nihaljain pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new b8f8c1ac52d HBASE-29244 Support admin users acl setting with LDAP (Web 
UI only) (#6923)
b8f8c1ac52d is described below

commit b8f8c1ac52d8b8f95cb194175ccf6db875426aee
Author: Nihal Jain <nihalj...@apache.org>
AuthorDate: Sat May 31 10:57:32 2025 +0530

    HBASE-29244 Support admin users acl setting with LDAP (Web UI only) (#6923)
    
    Signed-off-by: Nick Dimiduk <ndimi...@apache.org>
    Reviewed-by: Dávid Paksy <paksyda...@gmail.com>
    
    (cherry picked from commit 06a74f12f2ce1d58c7f01335b4b883fc15ba3699)
---
 .../org/apache/hadoop/hbase/http/HttpServer.java   |   5 +
 .../org/apache/hadoop/hbase/http/InfoServer.java   |  29 ++++-
 .../hadoop/hbase/http/LdapServerTestBase.java      | 124 +++++++++++++++++++++
 ...stLdapHttpServer.java => TestLdapAdminACL.java} | 106 ++++++++----------
 .../hadoop/hbase/http/TestLdapHttpServer.java      |  79 ++-----------
 .../hbase/http/TestProxyUserSpnegoHttpServer.java  |  17 +--
 6 files changed, 207 insertions(+), 153 deletions(-)

diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
index d5af8df1c7f..36a101b6ac7 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/HttpServer.java
@@ -148,6 +148,11 @@ public class HttpServer implements FilterContainer {
     HTTP_SPNEGO_AUTHENTICATION_PREFIX + "admin.users";
   public static final String HTTP_SPNEGO_AUTHENTICATION_ADMIN_GROUPS_KEY =
     HTTP_SPNEGO_AUTHENTICATION_PREFIX + "admin.groups";
+
+  static final String HTTP_LDAP_AUTHENTICATION_PREFIX = 
HTTP_AUTHENTICATION_PREFIX + "ldap.";
+  public static final String HTTP_LDAP_AUTHENTICATION_ADMIN_USERS_KEY =
+    HTTP_LDAP_AUTHENTICATION_PREFIX + "admin.users";
+
   public static final String HTTP_PRIVILEGED_CONF_KEY =
     "hbase.security.authentication.ui.config.protected";
   public static final String HTTP_UI_NO_CACHE_ENABLE_KEY = 
"hbase.http.filter.no-store.enable";
diff --git 
a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java 
b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
index c44222b8334..aa25ef42762 100644
--- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
+++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/InfoServer.java
@@ -77,18 +77,23 @@ public class InfoServer {
           c.get("ssl.server.truststore.type", "jks"));
       builder.excludeCiphers(c.get("ssl.server.exclude.cipher.list"));
     }
+
+    final String httpAuthType = c.get(HttpServer.HTTP_UI_AUTHENTICATION, 
"").toLowerCase();
     // Enable SPNEGO authentication
-    if ("kerberos".equalsIgnoreCase(c.get(HttpServer.HTTP_UI_AUTHENTICATION, 
null))) {
+    if ("kerberos".equals(httpAuthType)) {
       
builder.setUsernameConfKey(HttpServer.HTTP_SPNEGO_AUTHENTICATION_PRINCIPAL_KEY)
         .setKeytabConfKey(HttpServer.HTTP_SPNEGO_AUTHENTICATION_KEYTAB_KEY)
         
.setKerberosNameRulesKey(HttpServer.HTTP_SPNEGO_AUTHENTICATION_KRB_NAME_KEY)
         
.setSignatureSecretFileKey(HttpServer.HTTP_AUTHENTICATION_SIGNATURE_SECRET_FILE_KEY)
         .setSecurityEnabled(true);
+    }
 
-      // Set an admin ACL on sensitive webUI endpoints
+    // Set an admin ACL on sensitive webUI endpoints (works only if SPNEGO or 
LDAP is enabled)
+    if ("ldap".equals(httpAuthType) || "kerberos".equals(httpAuthType)) {
       AccessControlList acl = buildAdminAcl(c);
       builder.setACL(acl);
     }
+
     this.httpServer = builder.build();
   }
 
@@ -96,15 +101,27 @@ public class InfoServer {
    * Builds an ACL that will restrict the users who can issue commands to 
endpoints on the UI which
    * are meant only for administrators.
    */
-  AccessControlList buildAdminAcl(Configuration conf) {
-    final String userGroups = 
conf.get(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ADMIN_USERS_KEY, null);
+  static AccessControlList buildAdminAcl(Configuration conf) {
+    // Initialize admin users based on whether http ui auth is set to ldap or 
kerberos
+    String httpAuthType = conf.get(HttpServer.HTTP_UI_AUTHENTICATION, 
"").toLowerCase();
+    final String adminUsers = getAdminUsers(conf, httpAuthType);
     final String adminGroups =
       conf.get(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ADMIN_GROUPS_KEY, null);
-    if (userGroups == null && adminGroups == null) {
+    if (adminUsers == null && adminGroups == null) {
       // Backwards compatibility - if the user doesn't have anything set, 
allow all users in.
       return new AccessControlList("*", null);
     }
-    return new AccessControlList(userGroups, adminGroups);
+    return new AccessControlList(adminUsers, adminGroups);
+  }
+
+  private static String getAdminUsers(Configuration conf, String httpAuthType) 
{
+    if ("kerberos".equals(httpAuthType)) {
+      return conf.get(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ADMIN_USERS_KEY, 
null);
+    } else if ("ldap".equals(httpAuthType)) {
+      return conf.get(HttpServer.HTTP_LDAP_AUTHENTICATION_ADMIN_USERS_KEY, 
null);
+    }
+    // If the auth type is not kerberos or ldap, return null
+    return null;
   }
 
   /**
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/LdapServerTestBase.java 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/LdapServerTestBase.java
new file mode 100644
index 00000000000..bbf35b8585f
--- /dev/null
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/LdapServerTestBase.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.http;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.directory.server.core.integ.CreateLdapServerRule;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.http.resource.JerseyResource;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for setting up and testing an HTTP server with LDAP 
authentication.
+ */
+public class LdapServerTestBase extends HttpServerFunctionalTest {
+  private static final Logger LOG = 
LoggerFactory.getLogger(LdapServerTestBase.class);
+
+  @ClassRule
+  public static CreateLdapServerRule ldapRule = new CreateLdapServerRule();
+
+  protected static HttpServer server;
+  protected static URL baseUrl;
+
+  private static final String AUTH_TYPE = "Basic ";
+
+  /**
+   * Sets up the HTTP server with LDAP authentication before any tests are run.
+   * @throws Exception if an error occurs during server setup
+   */
+  @BeforeClass
+  public static void setupServer() throws Exception {
+    Configuration conf = new Configuration();
+    setLdapConfigurations(conf);
+
+    server = createTestServer(conf);
+    server.addUnprivilegedServlet("echo", "/echo", 
TestHttpServer.EchoServlet.class);
+    
server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), 
"/jersey/*");
+    server.start();
+
+    baseUrl = getServerURL(server);
+    LOG.info("HTTP server started: " + baseUrl);
+  }
+
+  /**
+   * Stops the HTTP server after all tests are completed.
+   * @throws Exception if an error occurs during server shutdown
+   */
+  @AfterClass
+  public static void stopServer() throws Exception {
+    try {
+      if (null != server) {
+        server.stop();
+      }
+    } catch (Exception e) {
+      LOG.info("Failed to stop info server", e);
+    }
+  }
+
+  /**
+   * Configures the provided Configuration object for LDAP authentication.
+   * @param conf the Configuration object to set LDAP properties on
+   * @return the configured Configuration object
+   */
+  protected static void setLdapConfigurations(Configuration conf) {
+    conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);
+
+    // Enable LDAP (pre-req)
+    conf.set(HttpServer.HTTP_UI_AUTHENTICATION, "ldap");
+    conf.set(HttpServer.FILTER_INITIALIZERS_PROPERTY,
+      "org.apache.hadoop.hbase.http.lib.AuthenticationFilterInitializer");
+    conf.set("hadoop.http.authentication.type", "ldap");
+    conf.set("hadoop.http.authentication.ldap.providerurl", 
String.format("ldap://%s:%s";,
+      LdapConstants.LDAP_SERVER_ADDR, ldapRule.getLdapServer().getPort()));
+    conf.set("hadoop.http.authentication.ldap.enablestarttls", "false");
+    conf.set("hadoop.http.authentication.ldap.basedn", 
LdapConstants.LDAP_BASE_DN);
+  }
+
+  /**
+   * Generates a Basic Authentication header from the provided credentials.
+   * @param credentials the credentials to encode
+   * @return the Basic Authentication header
+   */
+  private String getBasicAuthHeader(String credentials) {
+    return AUTH_TYPE + new Base64(0).encodeToString(credentials.getBytes());
+  }
+
+  /**
+   * Opens an HTTP connection to the specified endpoint with optional Basic 
Authentication.
+   * @param endpoint    the endpoint to connect to
+   * @param credentials the credentials for Basic Authentication (optional)
+   * @return the opened HttpURLConnection
+   * @throws IOException if an error occurs while opening the connection
+   */
+  protected HttpURLConnection openConnection(String endpoint, String 
credentials)
+    throws IOException {
+    URL url = new URL(getServerURL(server) + endpoint);
+    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+    if (credentials != null) {
+      conn.setRequestProperty("Authorization", 
getBasicAuthHeader(credentials));
+    }
+    return conn;
+  }
+}
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapAdminACL.java
similarity index 53%
copy from 
hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java
copy to 
hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapAdminACL.java
index 8bb48d50753..45986550963 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapAdminACL.java
@@ -21,21 +21,18 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.net.URL;
-import org.apache.commons.codec.binary.Base64;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.ContextEntry;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.annotations.CreatePartition;
-import org.apache.directory.server.core.integ.CreateLdapServerRule;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeys;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.http.resource.JerseyResource;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
@@ -44,97 +41,88 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Test class for LDAP authentication on the HttpServer.
+ * Test class for admin ACLs with LDAP authentication on the HttpServer.
  */
 @Category({ MiscTests.class, SmallTests.class })
 @CreateLdapServer(
     transports = { @CreateTransport(protocol = "LDAP", address = 
LdapConstants.LDAP_SERVER_ADDR), })
-@CreateDS(allowAnonAccess = true,
+@CreateDS(name = "TestLdapAdminACL", allowAnonAccess = true,
     partitions = { @CreatePartition(name = "Test_Partition", suffix = 
LdapConstants.LDAP_BASE_DN,
         contextEntry = @ContextEntry(entryLdif = "dn: " + 
LdapConstants.LDAP_BASE_DN + " \n"
           + "dc: example\n" + "objectClass: top\n" + "objectClass: 
domain\n\n")) })
 @ApplyLdifs({ "dn: uid=bjones," + LdapConstants.LDAP_BASE_DN, "cn: Bob Jones", 
"sn: Jones",
-  "objectClass: inetOrgPerson", "uid: bjones", "userPassword: p@ssw0rd" })
-public class TestLdapHttpServer extends HttpServerFunctionalTest {
+  "objectClass: inetOrgPerson", "uid: bjones", "userPassword: p@ssw0rd",
+
+  "dn: uid=jdoe," + LdapConstants.LDAP_BASE_DN, "cn: John Doe", "sn: Doe",
+  "objectClass: inetOrgPerson", "uid: jdoe", "userPassword: secure123" })
+public class TestLdapAdminACL extends LdapServerTestBase {
 
   @ClassRule
   public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestLdapHttpServer.class);
-  @ClassRule
-  public static CreateLdapServerRule serverRule = new CreateLdapServerRule();
-
-  private static final Logger LOG = 
LoggerFactory.getLogger(TestLdapHttpServer.class);
+    HBaseClassTestRule.forClass(TestLdapAdminACL.class);
+  private static final Logger LOG = 
LoggerFactory.getLogger(TestLdapAdminACL.class);
 
-  private static HttpServer server;
-  private static URL baseUrl;
+  private static final String ADMIN_CREDENTIALS = "bjones:p@ssw0rd";
+  private static final String NON_ADMIN_CREDENTIALS = "jdoe:secure123";
+  private static final String WRONG_CREDENTIALS = "bjones:password";
 
   @BeforeClass
   public static void setupServer() throws Exception {
     Configuration conf = new Configuration();
-    buildLdapConfiguration(conf);
-    server = createTestServer(conf);
+    setLdapConfigurationWithACLs(conf);
+
+    server = createTestServer(conf, InfoServer.buildAdminAcl(conf));
     server.addUnprivilegedServlet("echo", "/echo", 
TestHttpServer.EchoServlet.class);
+    // we will reuse /jmx which is a privileged servlet
     
server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), 
"/jersey/*");
     server.start();
-    baseUrl = getServerURL(server);
 
+    baseUrl = getServerURL(server);
     LOG.info("HTTP server started: " + baseUrl);
   }
 
-  @AfterClass
-  public static void stopServer() throws Exception {
-    try {
-      if (null != server) {
-        server.stop();
-      }
-    } catch (Exception e) {
-      LOG.info("Failed to stop info server", e);
-    }
-  }
-
-  private static Configuration buildLdapConfiguration(Configuration conf) {
+  private static void setLdapConfigurationWithACLs(Configuration conf) {
+    setLdapConfigurations(conf);
 
-    conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);
+    // Enable LDAP admin ACL
+    conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, 
true);
+    
conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_INSTRUMENTATION_REQUIRES_ADMIN,
 true);
+    conf.set(HttpServer.HTTP_LDAP_AUTHENTICATION_ADMIN_USERS_KEY, "bjones");
+  }
 
-    // Enable LDAP (pre-req)
-    conf.set(HttpServer.HTTP_UI_AUTHENTICATION, "ldap");
-    conf.set(HttpServer.FILTER_INITIALIZERS_PROPERTY,
-      "org.apache.hadoop.hbase.http.lib.AuthenticationFilterInitializer");
-    conf.set("hadoop.http.authentication.type", "ldap");
-    conf.set("hadoop.http.authentication.ldap.providerurl", 
String.format("ldap://%s:%s";,
-      LdapConstants.LDAP_SERVER_ADDR, serverRule.getLdapServer().getPort()));
-    conf.set("hadoop.http.authentication.ldap.enablestarttls", "false");
-    conf.set("hadoop.http.authentication.ldap.basedn", 
LdapConstants.LDAP_BASE_DN);
-    return conf;
+  @Test
+  public void testAdminAllowedUnprivilegedServletAccess() throws IOException {
+    HttpURLConnection conn = openConnection("/echo?a=b", ADMIN_CREDENTIALS);
+    assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
   }
 
   @Test
-  public void testUnauthorizedClientsDisallowed() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode());
+  public void testAdminAllowedPrivilegedServletAccess() throws IOException {
+    HttpURLConnection conn = openConnection("/jmx", ADMIN_CREDENTIALS);
+    assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
   }
 
   @Test
-  public void testAllowedClient() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    final Base64 base64 = new Base64(0);
-    String userCredentials = "bjones:p@ssw0rd";
-    String basicAuth = "Basic " + 
base64.encodeToString(userCredentials.getBytes());
-    conn.setRequestProperty("Authorization", basicAuth);
+  public void testNonAdminAllowedUnprivilegedServletAccess() throws 
IOException {
+    HttpURLConnection conn = openConnection("/echo?a=b", 
NON_ADMIN_CREDENTIALS);
     assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
   }
 
   @Test
-  public void testWrongAuthClientsDisallowed() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    final Base64 base64 = new Base64(0);
-    String userCredentials = "bjones:password";
-    String basicAuth = "Basic " + 
base64.encodeToString(userCredentials.getBytes());
-    conn.setRequestProperty("Authorization", basicAuth);
+  public void testNonAdminDisallowedPrivilegedServletAccess() throws 
IOException {
+    HttpURLConnection conn = openConnection("/jmx", NON_ADMIN_CREDENTIALS);
     assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode());
   }
 
+  @Test
+  public void testWrongAuthDisallowedUnprivilegedServletAccess() throws 
IOException {
+    HttpURLConnection conn = openConnection("/echo?a=b", WRONG_CREDENTIALS);
+    assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode());
+  }
+
+  @Test
+  public void testWrongAuthDisallowedPrivilegedServletAccess() throws 
IOException {
+    HttpURLConnection conn = openConnection("/jmx", WRONG_CREDENTIALS);
+    assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode());
+  }
 }
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java
index 8bb48d50753..bff4dc9d959 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestLdapHttpServer.java
@@ -21,27 +21,18 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.net.URL;
-import org.apache.commons.codec.binary.Base64;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.ContextEntry;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.annotations.CreatePartition;
-import org.apache.directory.server.core.integ.CreateLdapServerRule;
-import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
-import org.apache.hadoop.hbase.http.resource.JerseyResource;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Test class for LDAP authentication on the HttpServer.
@@ -49,92 +40,36 @@ import org.slf4j.LoggerFactory;
 @Category({ MiscTests.class, SmallTests.class })
 @CreateLdapServer(
     transports = { @CreateTransport(protocol = "LDAP", address = 
LdapConstants.LDAP_SERVER_ADDR), })
-@CreateDS(allowAnonAccess = true,
+@CreateDS(name = "TestLdapHttpServer", allowAnonAccess = true,
     partitions = { @CreatePartition(name = "Test_Partition", suffix = 
LdapConstants.LDAP_BASE_DN,
         contextEntry = @ContextEntry(entryLdif = "dn: " + 
LdapConstants.LDAP_BASE_DN + " \n"
           + "dc: example\n" + "objectClass: top\n" + "objectClass: 
domain\n\n")) })
 @ApplyLdifs({ "dn: uid=bjones," + LdapConstants.LDAP_BASE_DN, "cn: Bob Jones", 
"sn: Jones",
   "objectClass: inetOrgPerson", "uid: bjones", "userPassword: p@ssw0rd" })
-public class TestLdapHttpServer extends HttpServerFunctionalTest {
+public class TestLdapHttpServer extends LdapServerTestBase {
 
   @ClassRule
   public static final HBaseClassTestRule CLASS_RULE =
     HBaseClassTestRule.forClass(TestLdapHttpServer.class);
-  @ClassRule
-  public static CreateLdapServerRule serverRule = new CreateLdapServerRule();
-
-  private static final Logger LOG = 
LoggerFactory.getLogger(TestLdapHttpServer.class);
-
-  private static HttpServer server;
-  private static URL baseUrl;
-
-  @BeforeClass
-  public static void setupServer() throws Exception {
-    Configuration conf = new Configuration();
-    buildLdapConfiguration(conf);
-    server = createTestServer(conf);
-    server.addUnprivilegedServlet("echo", "/echo", 
TestHttpServer.EchoServlet.class);
-    
server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), 
"/jersey/*");
-    server.start();
-    baseUrl = getServerURL(server);
-
-    LOG.info("HTTP server started: " + baseUrl);
-  }
 
-  @AfterClass
-  public static void stopServer() throws Exception {
-    try {
-      if (null != server) {
-        server.stop();
-      }
-    } catch (Exception e) {
-      LOG.info("Failed to stop info server", e);
-    }
-  }
-
-  private static Configuration buildLdapConfiguration(Configuration conf) {
-
-    conf.setInt(HttpServer.HTTP_MAX_THREADS, TestHttpServer.MAX_THREADS);
-
-    // Enable LDAP (pre-req)
-    conf.set(HttpServer.HTTP_UI_AUTHENTICATION, "ldap");
-    conf.set(HttpServer.FILTER_INITIALIZERS_PROPERTY,
-      "org.apache.hadoop.hbase.http.lib.AuthenticationFilterInitializer");
-    conf.set("hadoop.http.authentication.type", "ldap");
-    conf.set("hadoop.http.authentication.ldap.providerurl", 
String.format("ldap://%s:%s";,
-      LdapConstants.LDAP_SERVER_ADDR, serverRule.getLdapServer().getPort()));
-    conf.set("hadoop.http.authentication.ldap.enablestarttls", "false");
-    conf.set("hadoop.http.authentication.ldap.basedn", 
LdapConstants.LDAP_BASE_DN);
-    return conf;
-  }
+  private static final String BJONES_CREDENTIALS = "bjones:p@ssw0rd";
+  private static final String WRONG_CREDENTIALS = "bjones:password";
 
   @Test
   public void testUnauthorizedClientsDisallowed() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+    HttpURLConnection conn = openConnection("/echo?a=b", null);
     assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode());
   }
 
   @Test
   public void testAllowedClient() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    final Base64 base64 = new Base64(0);
-    String userCredentials = "bjones:p@ssw0rd";
-    String basicAuth = "Basic " + 
base64.encodeToString(userCredentials.getBytes());
-    conn.setRequestProperty("Authorization", basicAuth);
+    HttpURLConnection conn = openConnection("/echo?a=b", BJONES_CREDENTIALS);
     assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
   }
 
   @Test
   public void testWrongAuthClientsDisallowed() throws IOException {
-    URL url = new URL(getServerURL(server), "/echo?a=b");
-    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
-    final Base64 base64 = new Base64(0);
-    String userCredentials = "bjones:password";
-    String basicAuth = "Basic " + 
base64.encodeToString(userCredentials.getBytes());
-    conn.setRequestProperty("Authorization", basicAuth);
+    HttpURLConnection conn = openConnection("/echo?a=b", WRONG_CREDENTIALS);
     assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode());
   }
-
 }
diff --git 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestProxyUserSpnegoHttpServer.java
 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestProxyUserSpnegoHttpServer.java
index 4b900dfe6de..9c1caa1d16c 100644
--- 
a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestProxyUserSpnegoHttpServer.java
+++ 
b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/TestProxyUserSpnegoHttpServer.java
@@ -126,7 +126,7 @@ public class TestProxyUserSpnegoHttpServer extends 
HttpServerFunctionalTest {
     setupUser(kdc, infoServerKeytab, serverPrincipal);
 
     buildSpnegoConfiguration(conf, serverPrincipal, infoServerKeytab);
-    AccessControlList acl = buildAdminAcl(conf);
+    AccessControlList acl = InfoServer.buildAdminAcl(conf);
 
     server = createTestServerWithSecurityAndAcl(conf, acl);
     server.addPrivilegedServlet("echo", "/echo", EchoServlet.class);
@@ -182,21 +182,6 @@ public class TestProxyUserSpnegoHttpServer extends 
HttpServerFunctionalTest {
     return conf;
   }
 
-  /**
-   * Builds an ACL that will restrict the users who can issue commands to 
endpoints on the UI which
-   * are meant only for administrators.
-   */
-  public static AccessControlList buildAdminAcl(Configuration conf) {
-    final String userGroups = 
conf.get(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ADMIN_USERS_KEY, null);
-    final String adminGroups =
-      conf.get(HttpServer.HTTP_SPNEGO_AUTHENTICATION_ADMIN_GROUPS_KEY, null);
-    if (userGroups == null && adminGroups == null) {
-      // Backwards compatibility - if the user doesn't have anything set, 
allow all users in.
-      return new AccessControlList("*", null);
-    }
-    return new AccessControlList(userGroups, adminGroups);
-  }
-
   @Test
   public void testProxyAllowed() throws Exception {
     testProxy(WHEEL_PRINCIPAL, PRIVILEGED_PRINCIPAL, 
HttpURLConnection.HTTP_OK, null);

Reply via email to