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.security;
019
020import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getClientKeytabForTesting;
021import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getClientPrincipalForTesting;
022import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
023import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
024import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getSecuredConfiguration;
025import static org.junit.Assert.assertEquals;
026import static org.junit.Assert.assertFalse;
027import static org.junit.Assert.assertNotNull;
028import static org.junit.Assert.assertTrue;
029
030import java.io.File;
031import java.io.IOException;
032
033import org.apache.hadoop.conf.Configuration;
034import org.apache.hadoop.hbase.AuthUtil;
035import org.apache.hadoop.hbase.HBaseClassTestRule;
036import org.apache.hadoop.hbase.HBaseTestingUtility;
037import org.apache.hadoop.hbase.testclassification.SecurityTests;
038import org.apache.hadoop.hbase.testclassification.SmallTests;
039import org.apache.hadoop.minikdc.MiniKdc;
040import org.apache.hadoop.security.UserGroupInformation;
041import org.junit.AfterClass;
042import org.junit.BeforeClass;
043import org.junit.ClassRule;
044import org.junit.Test;
045import org.junit.experimental.categories.Category;
046
047@Category({ SecurityTests.class, SmallTests.class })
048public class TestUsersOperationsWithSecureHadoop {
049
050  @ClassRule
051  public static final HBaseClassTestRule CLASS_RULE =
052      HBaseClassTestRule.forClass(TestUsersOperationsWithSecureHadoop.class);
053
054  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
055  private static final File KEYTAB_FILE = new File(TEST_UTIL.getDataTestDir("keytab").toUri()
056      .getPath());
057
058  private static MiniKdc KDC;
059
060  private static String HOST = "localhost";
061
062  private static String PRINCIPAL;
063
064  private static String CLIENT_NAME;
065
066  @BeforeClass
067  public static void setUp() throws Exception {
068    KDC = TEST_UTIL.setupMiniKdc(KEYTAB_FILE);
069    PRINCIPAL = "hbase/" + HOST;
070    CLIENT_NAME = "foo";
071    KDC.createPrincipal(KEYTAB_FILE, PRINCIPAL, CLIENT_NAME);
072    HBaseKerberosUtils.setPrincipalForTesting(PRINCIPAL + "@" + KDC.getRealm());
073    HBaseKerberosUtils.setKeytabFileForTesting(KEYTAB_FILE.getAbsolutePath());
074    HBaseKerberosUtils.setClientPrincipalForTesting(CLIENT_NAME + "@" + KDC.getRealm());
075    HBaseKerberosUtils.setClientKeytabForTesting(KEYTAB_FILE.getAbsolutePath());
076  }
077
078  @AfterClass
079  public static void tearDown() throws IOException {
080    if (KDC != null) {
081      KDC.stop();
082    }
083    TEST_UTIL.cleanupTestDir();
084  }
085
086  /**
087   * test login with security enabled configuration To run this test, we must specify the following
088   * system properties:
089   * <p>
090   * <b> hbase.regionserver.kerberos.principal </b>
091   * <p>
092   * <b> hbase.regionserver.keytab.file </b>
093   * @throws IOException
094   */
095  @Test
096  public void testUserLoginInSecureHadoop() throws Exception {
097    // Default login is system user.
098    UserGroupInformation defaultLogin = UserGroupInformation.getCurrentUser();
099
100    String nnKeyTab = getKeytabFileForTesting();
101    String dnPrincipal = getPrincipalForTesting();
102
103    assertNotNull("KerberosKeytab was not specified", nnKeyTab);
104    assertNotNull("KerberosPrincipal was not specified", dnPrincipal);
105
106    Configuration conf = getSecuredConfiguration();
107    UserGroupInformation.setConfiguration(conf);
108
109    User.login(conf, HBaseKerberosUtils.KRB_KEYTAB_FILE, HBaseKerberosUtils.KRB_PRINCIPAL,
110      "localhost");
111    UserGroupInformation successLogin = UserGroupInformation.getLoginUser();
112    assertFalse("ugi should be different in in case success login",
113      defaultLogin.equals(successLogin));
114  }
115
116  @Test
117  public void testLoginWithUserKeytabAndPrincipal() throws Exception {
118    String clientKeytab = getClientKeytabForTesting();
119    String clientPrincipal = getClientPrincipalForTesting();
120    assertNotNull("Path for client keytab is not specified.", clientKeytab);
121    assertNotNull("Client principal is not specified.", clientPrincipal);
122
123    Configuration conf = getSecuredConfiguration();
124    conf.set(AuthUtil.HBASE_CLIENT_KEYTAB_FILE, clientKeytab);
125    conf.set(AuthUtil.HBASE_CLIENT_KERBEROS_PRINCIPAL, clientPrincipal);
126    UserGroupInformation.setConfiguration(conf);
127
128    UserProvider provider = UserProvider.instantiate(conf);
129    assertTrue("Client principal or keytab is empty", provider.shouldLoginFromKeytab());
130
131    provider.login(AuthUtil.HBASE_CLIENT_KEYTAB_FILE, AuthUtil.HBASE_CLIENT_KERBEROS_PRINCIPAL);
132    User loginUser = provider.getCurrent();
133    assertEquals(CLIENT_NAME, loginUser.getShortName());
134    assertEquals(getClientPrincipalForTesting(), loginUser.getName());
135  }
136
137  @Test
138  public void testAuthUtilLogin() throws Exception {
139    String clientKeytab = getClientKeytabForTesting();
140    String clientPrincipal = getClientPrincipalForTesting();
141    Configuration conf = getSecuredConfiguration();
142    conf.set(AuthUtil.HBASE_CLIENT_KEYTAB_FILE, clientKeytab);
143    conf.set(AuthUtil.HBASE_CLIENT_KERBEROS_PRINCIPAL, clientPrincipal);
144    UserGroupInformation.setConfiguration(conf);
145
146    User user = AuthUtil.loginClient(conf);
147    assertTrue(user.isLoginFromKeytab());
148    assertEquals(CLIENT_NAME, user.getShortName());
149    assertEquals(getClientPrincipalForTesting(), user.getName());
150  }
151}