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);