This is an automated email from the ASF dual-hosted git repository.
nihaljain pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new b4a341bcc7a HBASE-29244 Support admin users acl setting with LDAP (Web
UI only) (#6923) (#7053)
b4a341bcc7a is described below
commit b4a341bcc7a60b0dda44cff768f3973035ca80c3
Author: Nihal Jain <[email protected]>
AuthorDate: Sat May 31 18:20:38 2025 +0530
HBASE-29244 Support admin users acl setting with LDAP (Web UI only) (#6923)
(#7053)
* Exclude test files which do not work with hadoop-2
Signed-off-by: Nick Dimiduk <[email protected]>
Reviewed-by: Dávid Paksy <[email protected]>
(cherry picked from commit 06a74f12f2ce1d58c7f01335b4b883fc15ba3699)
---
hbase-http/pom.xml | 2 +
.../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 +--
7 files changed, 209 insertions(+), 153 deletions(-)
diff --git a/hbase-http/pom.xml b/hbase-http/pom.xml
index 7ab2813abb5..47373b25e77 100644
--- a/hbase-http/pom.xml
+++ b/hbase-http/pom.xml
@@ -408,6 +408,8 @@
-->
<testExcludes>
<testExclude>**/org/apache/hadoop/hbase/http/TestLdapHttpServer**</testExclude>
+
<testExclude>**/org/apache/hadoop/hbase/http/LdapServerTestBase**</testExclude>
+
<testExclude>**/org/apache/hadoop/hbase/http/TestLdapAdminACL**</testExclude>
</testExcludes>
</configuration>
</plugin>
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 ed5a815cc03..e6842bbb02e 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);