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.Assert.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.HBaseClassTestRule; 033import org.apache.hadoop.hbase.http.resource.JerseyResource; 034import org.apache.hadoop.hbase.testclassification.MiscTests; 035import org.apache.hadoop.hbase.testclassification.SmallTests; 036import org.junit.BeforeClass; 037import org.junit.ClassRule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043/** 044 * Test class for admin ACLs with LDAP authentication on the HttpServer. 045 */ 046@Category({ MiscTests.class, SmallTests.class }) 047@CreateLdapServer( 048 transports = { @CreateTransport(protocol = "LDAP", address = LdapConstants.LDAP_SERVER_ADDR), }) 049@CreateDS(name = "TestLdapAdminACL", allowAnonAccess = true, 050 partitions = { @CreatePartition(name = "Test_Partition", suffix = LdapConstants.LDAP_BASE_DN, 051 contextEntry = @ContextEntry(entryLdif = "dn: " + LdapConstants.LDAP_BASE_DN + " \n" 052 + "dc: example\n" + "objectClass: top\n" + "objectClass: domain\n\n")) }) 053@ApplyLdifs({ "dn: uid=bjones," + LdapConstants.LDAP_BASE_DN, "cn: Bob Jones", "sn: Jones", 054 "objectClass: inetOrgPerson", "uid: bjones", "userPassword: p@ssw0rd", 055 056 "dn: uid=jdoe," + LdapConstants.LDAP_BASE_DN, "cn: John Doe", "sn: Doe", 057 "objectClass: inetOrgPerson", "uid: jdoe", "userPassword: secure123" }) 058public class TestLdapAdminACL extends LdapServerTestBase { 059 060 @ClassRule 061 public static final HBaseClassTestRule CLASS_RULE = 062 HBaseClassTestRule.forClass(TestLdapAdminACL.class); 063 private static final Logger LOG = LoggerFactory.getLogger(TestLdapAdminACL.class); 064 065 private static final String ADMIN_CREDENTIALS = "bjones:p@ssw0rd"; 066 private static final String NON_ADMIN_CREDENTIALS = "jdoe:secure123"; 067 private static final String WRONG_CREDENTIALS = "bjones:password"; 068 069 @BeforeClass 070 public static void setupServer() throws Exception { 071 Configuration conf = new Configuration(); 072 setLdapConfigurationWithACLs(conf); 073 074 server = createTestServer(conf, InfoServer.buildAdminAcl(conf)); 075 server.addUnprivilegedServlet("echo", "/echo", TestHttpServer.EchoServlet.class); 076 // we will reuse /jmx which is a privileged servlet 077 server.addJerseyResourcePackage(JerseyResource.class.getPackage().getName(), "/jersey/*"); 078 server.start(); 079 080 baseUrl = getServerURL(server); 081 LOG.info("HTTP server started: " + baseUrl); 082 } 083 084 private static void setLdapConfigurationWithACLs(Configuration conf) { 085 setLdapConfigurations(conf); 086 087 // Enable LDAP admin ACL 088 conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, true); 089 conf.setBoolean(CommonConfigurationKeys.HADOOP_SECURITY_INSTRUMENTATION_REQUIRES_ADMIN, true); 090 conf.set(HttpServer.HTTP_LDAP_AUTHENTICATION_ADMIN_USERS_KEY, "bjones"); 091 } 092 093 @Test 094 public void testAdminAllowedUnprivilegedServletAccess() throws IOException { 095 HttpURLConnection conn = openConnection("/echo?a=b", ADMIN_CREDENTIALS); 096 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 097 } 098 099 @Test 100 public void testAdminAllowedPrivilegedServletAccess() throws IOException { 101 HttpURLConnection conn = openConnection("/jmx", ADMIN_CREDENTIALS); 102 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 103 } 104 105 @Test 106 public void testNonAdminAllowedUnprivilegedServletAccess() throws IOException { 107 HttpURLConnection conn = openConnection("/echo?a=b", NON_ADMIN_CREDENTIALS); 108 assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); 109 } 110 111 @Test 112 public void testNonAdminDisallowedPrivilegedServletAccess() throws IOException { 113 HttpURLConnection conn = openConnection("/jmx", NON_ADMIN_CREDENTIALS); 114 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 115 } 116 117 @Test 118 public void testWrongAuthDisallowedUnprivilegedServletAccess() throws IOException { 119 HttpURLConnection conn = openConnection("/echo?a=b", WRONG_CREDENTIALS); 120 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 121 } 122 123 @Test 124 public void testWrongAuthDisallowedPrivilegedServletAccess() throws IOException { 125 HttpURLConnection conn = openConnection("/jmx", WRONG_CREDENTIALS); 126 assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); 127 } 128}