001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.http; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021 022import java.io.IOException; 023import java.net.HttpURLConnection; 024import org.apache.directory.server.annotations.CreateLdapServer; 025import org.apache.directory.server.annotations.CreateTransport; 026import org.apache.directory.server.core.annotations.ApplyLdifs; 027import org.apache.directory.server.core.annotations.ContextEntry; 028import org.apache.directory.server.core.annotations.CreateDS; 029import org.apache.directory.server.core.annotations.CreatePartition; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.fs.CommonConfigurationKeys; 032import org.apache.hadoop.hbase.http.resource.JerseyResource; 033import org.apache.hadoop.hbase.testclassification.MiscTests; 034import org.apache.hadoop.hbase.testclassification.SmallTests; 035import org.junit.jupiter.api.BeforeAll; 036import org.junit.jupiter.api.Tag; 037import org.junit.jupiter.api.Test; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041/** 042 * Test class for admin ACLs with LDAP authentication on the HttpServer. 043 */ 044@Tag(MiscTests.TAG) 045@Tag(SmallTests.TAG) 046@CreateLdapServer( 047 transports = { @CreateTransport(protocol = "LDAP", address = LdapConstants.LDAP_SERVER_ADDR), }) 048@CreateDS(name = "TestLdapAdminACL", allowAnonAccess = true, 049 partitions = { @CreatePartition(name = "Test_Partition", suffix = LdapConstants.LDAP_BASE_DN, 050 contextEntry = @ContextEntry(entryLdif = "dn: " + LdapConstants.LDAP_BASE_DN + " \n" 051 + "dc: example\n" + "objectClass: top\n" + "objectClass: domain\n\n")) }) 052@ApplyLdifs({ "dn: uid=bjones," + LdapConstants.LDAP_BASE_DN, "cn: Bob Jones", "sn: Jones", 053 "objectClass: inetOrgPerson", "uid: bjones", "userPassword: p@ssw0rd", 054 055 "dn: uid=jdoe," + LdapConstants.LDAP_BASE_DN, "cn: John Doe", "sn: Doe", 056 "objectClass: inetOrgPerson", "uid: jdoe", "userPassword: secure123" }) 057public class TestLdapAdminACL extends LdapServerTestBase { 058 059 private static final Logger LOG = LoggerFactory.getLogger(TestLdapAdminACL.class); 060 061 private static final String ADMIN_CREDENTIALS = "bjones:p@ssw0rd"; 062 private static final String NON_ADMIN_CREDENTIALS = "jdoe:secure123"; 063 private static final String WRONG_CREDENTIALS = "bjones:password"; 064 065 @BeforeAll 066 public static void setupServer() throws Exception { 067 Configuration conf = new Configuration(); 068 setLdapConfigurationWithACLs(conf); 069 070 server = createTestServer(conf, InfoServer.buildAdminAcl(conf)); 071 server.addUnprivilegedServlet("echo", "/echo", TestHttpServer.EchoServlet.class); 072 // we will reuse /jmx which is a privileged servlet 073 server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), "/jersey/*"); 074 server.start(); 075 076 baseUrl = getServerURL(server); 077 LOG.info("HTTP server started: " + baseUrl); 078 } 079 080 private static void setLdapConfigurationWithACLs(Configuration conf) { 081 setLdapConfigurations(conf); 082 083 // Enable LDAP admin ACL 084 conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, true); 085 conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_INSTRUMENTATION_REQUIRES_ADMIN, true); 086 conf.set(HttpServer.HTTP_LDAP_AUTHENTICATION_ADMIN_USERS_KEY, "bjones"); 087 } 088 089 @Test 090 public void testAdminAllowedUnprivilegedServletAccess() throws IOException { 091 HttpURLConnection conn = openConnection("/echo?a=b", ADMIN_CREDENTIALS); 092 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 093 } 094 095 @Test 096 public void testAdminAllowedPrivilegedServletAccess() throws IOException { 097 HttpURLConnection conn = openConnection("/jmx", ADMIN_CREDENTIALS); 098 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 099 } 100 101 @Test 102 public void testNonAdminAllowedUnprivilegedServletAccess() throws IOException { 103 HttpURLConnection conn = openConnection("/echo?a=b", NON_ADMIN_CREDENTIALS); 104 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 105 } 106 107 @Test 108 public void testNonAdminDisallowedPrivilegedServletAccess() throws IOException { 109 HttpURLConnection conn = openConnection("/jmx", NON_ADMIN_CREDENTIALS); 110 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 111 } 112 113 @Test 114 public void testWrongAuthDisallowedUnprivilegedServletAccess() throws IOException { 115 HttpURLConnection conn = openConnection("/echo?a=b", WRONG_CREDENTIALS); 116 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 117 } 118 119 @Test 120 public void testWrongAuthDisallowedPrivilegedServletAccess() throws IOException { 121 HttpURLConnection conn = openConnection("/jmx", WRONG_CREDENTIALS); 122 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 123 } 124}