HBASE-8569. Improve coverage in package org.apache.hadoop.hbase.security. Contributed by Vadim Bondarev and Andrey Klochkov
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1537986 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
22b465ea1c
commit
8fb1958b67
|
@ -37,6 +37,7 @@ import javax.security.sasl.RealmChoiceCallback;
|
|||
import javax.security.sasl.Sasl;
|
||||
import javax.security.sasl.SaslClient;
|
||||
import javax.security.sasl.SaslException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
|
@ -45,6 +46,8 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* A utility class that encapsulates SASL logic for RPC client.
|
||||
* Copied from <code>org.apache.hadoop.security</code>
|
||||
|
@ -72,9 +75,9 @@ public class HBaseSaslRpcClient {
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Creating SASL " + AuthMethod.DIGEST.getMechanismName()
|
||||
+ " client to authenticate to service at " + token.getService());
|
||||
saslClient = Sasl.createSaslClient(new String[] { AuthMethod.DIGEST
|
||||
.getMechanismName() }, null, null, SaslUtil.SASL_DEFAULT_REALM,
|
||||
SaslUtil.SASL_PROPS, new SaslClientCallbackHandler(token));
|
||||
saslClient = createDigestSaslClient(
|
||||
new String[] { AuthMethod.DIGEST.getMechanismName() },
|
||||
SaslUtil.SASL_DEFAULT_REALM, new SaslClientCallbackHandler(token));
|
||||
break;
|
||||
case KERBEROS:
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
@ -93,9 +96,9 @@ public class HBaseSaslRpcClient {
|
|||
"Kerberos principal does not have the expected format: "
|
||||
+ serverPrincipal);
|
||||
}
|
||||
saslClient = Sasl.createSaslClient(new String[] { AuthMethod.KERBEROS
|
||||
.getMechanismName() }, null, names[0], names[1],
|
||||
SaslUtil.SASL_PROPS, null);
|
||||
saslClient = createKerberosSaslClient(
|
||||
new String[] { AuthMethod.KERBEROS.getMechanismName() },
|
||||
names[0], names[1]);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown authentication method " + method);
|
||||
|
@ -104,6 +107,19 @@ public class HBaseSaslRpcClient {
|
|||
throw new IOException("Unable to find SASL client implementation");
|
||||
}
|
||||
|
||||
protected SaslClient createDigestSaslClient(String[] mechanismNames,
|
||||
String saslDefaultRealm, CallbackHandler saslClientCallbackHandler)
|
||||
throws IOException {
|
||||
return Sasl.createSaslClient(mechanismNames, null, null, saslDefaultRealm,
|
||||
SaslUtil.SASL_PROPS, saslClientCallbackHandler);
|
||||
}
|
||||
|
||||
protected SaslClient createKerberosSaslClient(String[] mechanismNames,
|
||||
String userFirstPart, String userSecondPart) throws IOException {
|
||||
return Sasl.createSaslClient(mechanismNames, null, userFirstPart,
|
||||
userSecondPart, SaslUtil.SASL_PROPS, null);
|
||||
}
|
||||
|
||||
private static void readStatus(DataInputStream inStream) throws IOException {
|
||||
int status = inStream.readInt(); // read status
|
||||
if (status != SaslStatus.SUCCESS.state) {
|
||||
|
@ -234,7 +250,8 @@ public class HBaseSaslRpcClient {
|
|||
saslClient.dispose();
|
||||
}
|
||||
|
||||
private static class SaslClientCallbackHandler implements CallbackHandler {
|
||||
@VisibleForTesting
|
||||
static class SaslClientCallbackHandler implements CallbackHandler {
|
||||
private final String userName;
|
||||
private final char[] userPassword;
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.security;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
||||
import org.apache.hadoop.hbase.HBaseConfiguration;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
class HBaseKerberosUtils {
|
||||
public static final String KRB_PRINCIPAL = "hbase.regionserver.kerberos.principal";
|
||||
public static final String KRB_KEYTAB_FILE = "hbase.regionserver.keytab.file";
|
||||
|
||||
static boolean isKerberosPropertySetted() {
|
||||
String krbPrincipal = System.getProperty(KRB_PRINCIPAL);
|
||||
String krbKeytab = System.getProperty(KRB_KEYTAB_FILE);
|
||||
if (Strings.isNullOrEmpty(krbPrincipal) || Strings.isNullOrEmpty(krbKeytab)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setPrincipalForTesting(String principal) {
|
||||
setSystemProperty(KRB_PRINCIPAL, principal);
|
||||
}
|
||||
|
||||
static void setKeytabFileForTesting(String keytabFile) {
|
||||
setSystemProperty(KRB_KEYTAB_FILE, keytabFile);
|
||||
}
|
||||
|
||||
static void setSystemProperty(String propertyName, String propertyValue) {
|
||||
System.setProperty(propertyName, propertyValue);
|
||||
}
|
||||
|
||||
static String getKeytabFileForTesting() {
|
||||
return System.getProperty(KRB_KEYTAB_FILE);
|
||||
}
|
||||
|
||||
static String getPrincipalForTesting() {
|
||||
return System.getProperty(KRB_PRINCIPAL);
|
||||
}
|
||||
|
||||
static Configuration getConfigurationWoPrincipal() {
|
||||
Configuration conf = HBaseConfiguration.create();
|
||||
conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
|
||||
conf.set("hbase.security.authentication", "kerberos");
|
||||
conf.setBoolean("hbase.security.authorization", true);
|
||||
return conf;
|
||||
}
|
||||
|
||||
static Configuration getSecuredConfiguration() {
|
||||
Configuration conf = HBaseConfiguration.create();
|
||||
conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
|
||||
conf.set("hbase.security.authentication", "kerberos");
|
||||
conf.setBoolean("hbase.security.authorization", true);
|
||||
conf.set(KRB_KEYTAB_FILE, System.getProperty(KRB_KEYTAB_FILE));
|
||||
conf.set(KRB_PRINCIPAL, System.getProperty(KRB_PRINCIPAL));
|
||||
return conf;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
*
|
||||
* 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.security;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.TextOutputCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.sasl.RealmCallback;
|
||||
import javax.security.sasl.RealmChoiceCallback;
|
||||
import javax.security.sasl.SaslClient;
|
||||
|
||||
import org.apache.hadoop.hbase.SmallTests;
|
||||
import org.apache.hadoop.hbase.security.HBaseSaslRpcClient.SaslClientCallbackHandler;
|
||||
import org.apache.hadoop.io.DataInputBuffer;
|
||||
import org.apache.hadoop.io.DataOutputBuffer;
|
||||
import org.apache.hadoop.security.token.Token;
|
||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@Category(SmallTests.class)
|
||||
public class TestHBaseSaslRpcClient {
|
||||
|
||||
static {
|
||||
System.setProperty("java.security.krb5.realm", "DOMAIN.COM");
|
||||
System.setProperty("java.security.krb5.kdc", "DOMAIN.COM");
|
||||
}
|
||||
|
||||
static final String DEFAULT_USER_NAME = "principal";
|
||||
static final String DEFAULT_USER_PASSWORD = "password";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(TestHBaseSaslRpcClient.class);
|
||||
|
||||
@BeforeClass
|
||||
public static void before() {
|
||||
Logger.getRootLogger().setLevel(Level.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaslClientCallbackHandler() throws UnsupportedCallbackException {
|
||||
final Token<? extends TokenIdentifier> token = createTokenMock();
|
||||
when(token.getIdentifier()).thenReturn(DEFAULT_USER_NAME.getBytes());
|
||||
when(token.getPassword()).thenReturn(DEFAULT_USER_PASSWORD.getBytes());
|
||||
|
||||
final NameCallback nameCallback = mock(NameCallback.class);
|
||||
final PasswordCallback passwordCallback = mock(PasswordCallback.class);
|
||||
final RealmCallback realmCallback = mock(RealmCallback.class);
|
||||
final RealmChoiceCallback realmChoiceCallback = mock(RealmChoiceCallback.class);
|
||||
|
||||
Callback[] callbackArray = {nameCallback, passwordCallback,
|
||||
realmCallback, realmChoiceCallback};
|
||||
final SaslClientCallbackHandler saslClCallbackHandler = new SaslClientCallbackHandler(token);
|
||||
saslClCallbackHandler.handle(callbackArray);
|
||||
verify(nameCallback).setName(anyString());
|
||||
verify(realmCallback).setText(anyString());
|
||||
verify(passwordCallback).setPassword(any(char[].class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaslClientCallbackHandlerWithException() {
|
||||
final Token<? extends TokenIdentifier> token = createTokenMock();
|
||||
when(token.getIdentifier()).thenReturn(DEFAULT_USER_NAME.getBytes());
|
||||
when(token.getPassword()).thenReturn(DEFAULT_USER_PASSWORD.getBytes());
|
||||
final SaslClientCallbackHandler saslClCallbackHandler = new SaslClientCallbackHandler(token);
|
||||
try {
|
||||
saslClCallbackHandler.handle(new Callback[] { mock(TextOutputCallback.class) });
|
||||
} catch (UnsupportedCallbackException expEx) {
|
||||
//expected
|
||||
} catch (Exception ex) {
|
||||
fail("testSaslClientCallbackHandlerWithException error : " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHBaseSaslRpcClientCreation() throws Exception {
|
||||
//creation kerberos principal check section
|
||||
assertFalse(assertSuccessCreationKerberosPrincipal(null));
|
||||
assertFalse(assertSuccessCreationKerberosPrincipal("DOMAIN.COM"));
|
||||
assertFalse(assertSuccessCreationKerberosPrincipal("principal/DOMAIN.COM"));
|
||||
assertTrue(assertSuccessCreationKerberosPrincipal("principal/localhost@DOMAIN.COM"));
|
||||
|
||||
//creation digest principal check section
|
||||
assertFalse(assertSuccessCreationDigestPrincipal(null, null));
|
||||
assertFalse(assertSuccessCreationDigestPrincipal("", ""));
|
||||
assertFalse(assertSuccessCreationDigestPrincipal("", null));
|
||||
assertFalse(assertSuccessCreationDigestPrincipal(null, ""));
|
||||
assertTrue(assertSuccessCreationDigestPrincipal(DEFAULT_USER_NAME, DEFAULT_USER_PASSWORD));
|
||||
|
||||
//creation simple principal check section
|
||||
assertFalse(assertSuccessCreationSimplePrincipal("", ""));
|
||||
assertFalse(assertSuccessCreationSimplePrincipal(null, null));
|
||||
assertFalse(assertSuccessCreationSimplePrincipal(DEFAULT_USER_NAME, DEFAULT_USER_PASSWORD));
|
||||
|
||||
//exceptions check section
|
||||
assertTrue(assertIOExceptionThenSaslClientIsNull(DEFAULT_USER_NAME, DEFAULT_USER_PASSWORD));
|
||||
assertTrue(assertIOExceptionWhenGetStreamsBeforeConnectCall(
|
||||
DEFAULT_USER_NAME, DEFAULT_USER_PASSWORD));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthMethodReadWrite() throws IOException {
|
||||
DataInputBuffer in = new DataInputBuffer();
|
||||
DataOutputBuffer out = new DataOutputBuffer();
|
||||
|
||||
assertAuthMethodRead(in, AuthMethod.SIMPLE);
|
||||
assertAuthMethodRead(in, AuthMethod.KERBEROS);
|
||||
assertAuthMethodRead(in, AuthMethod.DIGEST);
|
||||
|
||||
assertAuthMethodWrite(out, AuthMethod.SIMPLE);
|
||||
assertAuthMethodWrite(out, AuthMethod.KERBEROS);
|
||||
assertAuthMethodWrite(out, AuthMethod.DIGEST);
|
||||
}
|
||||
|
||||
private void assertAuthMethodRead(DataInputBuffer in, AuthMethod authMethod)
|
||||
throws IOException {
|
||||
in.reset(new byte[] {authMethod.code}, 1);
|
||||
assertEquals(authMethod, AuthMethod.read(in));
|
||||
}
|
||||
|
||||
private void assertAuthMethodWrite(DataOutputBuffer out, AuthMethod authMethod)
|
||||
throws IOException {
|
||||
authMethod.write(out);
|
||||
assertEquals(authMethod.code, out.getData()[0]);
|
||||
out.reset();
|
||||
}
|
||||
|
||||
private boolean assertIOExceptionWhenGetStreamsBeforeConnectCall(String principal,
|
||||
String password) throws IOException {
|
||||
boolean inState = false;
|
||||
boolean outState = false;
|
||||
|
||||
HBaseSaslRpcClient rpcClient = new HBaseSaslRpcClient(AuthMethod.DIGEST,
|
||||
createTokenMockWithCredentials(principal, password), principal, false) {
|
||||
@Override
|
||||
public SaslClient createDigestSaslClient(String[] mechanismNames,
|
||||
String saslDefaultRealm, CallbackHandler saslClientCallbackHandler)
|
||||
throws IOException {
|
||||
return Mockito.mock(SaslClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaslClient createKerberosSaslClient(String[] mechanismNames,
|
||||
String userFirstPart, String userSecondPart) throws IOException {
|
||||
return Mockito.mock(SaslClient.class);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
rpcClient.getInputStream(Mockito.mock(InputStream.class));
|
||||
} catch(IOException ex) {
|
||||
//Sasl authentication exchange hasn't completed yet
|
||||
inState = true;
|
||||
}
|
||||
|
||||
try {
|
||||
rpcClient.getOutputStream(Mockito.mock(OutputStream.class));
|
||||
} catch(IOException ex) {
|
||||
//Sasl authentication exchange hasn't completed yet
|
||||
outState = true;
|
||||
}
|
||||
|
||||
return inState && outState;
|
||||
}
|
||||
|
||||
private boolean assertIOExceptionThenSaslClientIsNull(String principal, String password) {
|
||||
try {
|
||||
new HBaseSaslRpcClient(AuthMethod.DIGEST,
|
||||
createTokenMockWithCredentials(principal, password), principal, false) {
|
||||
@Override
|
||||
public SaslClient createDigestSaslClient(String[] mechanismNames,
|
||||
String saslDefaultRealm, CallbackHandler saslClientCallbackHandler)
|
||||
throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaslClient createKerberosSaslClient(String[] mechanismNames,
|
||||
String userFirstPart, String userSecondPart) throws IOException {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean assertSuccessCreationKerberosPrincipal(String principal) {
|
||||
HBaseSaslRpcClient rpcClient = null;
|
||||
try {
|
||||
rpcClient = createSaslRpcClientForKerberos(principal);
|
||||
} catch(Exception ex) {
|
||||
LOG.error(ex.getMessage(), ex);
|
||||
}
|
||||
return rpcClient != null;
|
||||
}
|
||||
|
||||
private boolean assertSuccessCreationDigestPrincipal(String principal, String password) {
|
||||
HBaseSaslRpcClient rpcClient = null;
|
||||
try {
|
||||
rpcClient = new HBaseSaslRpcClient(AuthMethod.DIGEST,
|
||||
createTokenMockWithCredentials(principal, password), principal, false);
|
||||
} catch(Exception ex) {
|
||||
LOG.error(ex.getMessage(), ex);
|
||||
}
|
||||
return rpcClient != null;
|
||||
}
|
||||
|
||||
private boolean assertSuccessCreationSimplePrincipal(String principal, String password) {
|
||||
HBaseSaslRpcClient rpcClient = null;
|
||||
try {
|
||||
rpcClient = createSaslRpcClientSimple(principal, password);
|
||||
} catch(Exception ex) {
|
||||
LOG.error(ex.getMessage(), ex);
|
||||
}
|
||||
return rpcClient != null;
|
||||
}
|
||||
|
||||
private HBaseSaslRpcClient createSaslRpcClientForKerberos(String principal)
|
||||
throws IOException {
|
||||
return new HBaseSaslRpcClient(AuthMethod.KERBEROS, createTokenMock(), principal, false);
|
||||
}
|
||||
|
||||
private Token<? extends TokenIdentifier> createTokenMockWithCredentials(
|
||||
String principal, String password)
|
||||
throws IOException {
|
||||
Token<? extends TokenIdentifier> token = createTokenMock();
|
||||
if (!Strings.isNullOrEmpty(principal) && !Strings.isNullOrEmpty(password)) {
|
||||
when(token.getIdentifier()).thenReturn(DEFAULT_USER_NAME.getBytes());
|
||||
when(token.getPassword()).thenReturn(DEFAULT_USER_PASSWORD.getBytes());
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private HBaseSaslRpcClient createSaslRpcClientSimple(String principal, String password)
|
||||
throws IOException {
|
||||
return new HBaseSaslRpcClient(AuthMethod.SIMPLE, createTokenMock(), principal, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Token<? extends TokenIdentifier> createTokenMock() {
|
||||
return mock(Token.class);
|
||||
}
|
||||
}
|
|
@ -18,19 +18,25 @@
|
|||
*/
|
||||
package org.apache.hadoop.hbase.security;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.CommonConfigurationKeys;
|
||||
import org.apache.hadoop.hbase.HBaseConfiguration;
|
||||
import org.apache.hadoop.hbase.SmallTests;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@Category(SmallTests.class)
|
||||
public class TestUser {
|
||||
|
@ -75,7 +81,7 @@ public class TestUser {
|
|||
assertEquals("User name in runAs() should match", "testuser", username);
|
||||
|
||||
// verify that nested contexts work
|
||||
user2.runAs(new PrivilegedExceptionAction(){
|
||||
user2.runAs(new PrivilegedExceptionAction<Object>(){
|
||||
public Object run() throws IOException, InterruptedException{
|
||||
String nestedName = user.runAs(action);
|
||||
assertEquals("Nest name should match nested user", "testuser", nestedName);
|
||||
|
@ -84,6 +90,22 @@ public class TestUser {
|
|||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
username = user.runAs(new PrivilegedAction<String>(){
|
||||
String result = null;
|
||||
@Override
|
||||
public String run() {
|
||||
try {
|
||||
return User.getCurrent().getName();
|
||||
} catch (IOException e) {
|
||||
result = "empty";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals("Current user within runAs() should match",
|
||||
"testuser", username);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,5 +128,48 @@ public class TestUser {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testUserGroupNames() throws Exception {
|
||||
final String username = "testuser";
|
||||
final ImmutableSet<String> singleGroups = ImmutableSet.of("group");
|
||||
final Configuration conf = HBaseConfiguration.create();
|
||||
User user = User.createUserForTesting(conf, username, singleGroups.toArray(new String[]{}));
|
||||
assertUserGroup(user, singleGroups);
|
||||
|
||||
final ImmutableSet<String> multiGroups = ImmutableSet.of("group", "group1", "group2");
|
||||
user = User.createUserForTesting(conf, username, multiGroups.toArray(new String[]{}));
|
||||
assertUserGroup(user, multiGroups);
|
||||
}
|
||||
|
||||
private void assertUserGroup(User user, ImmutableSet<String> groups) {
|
||||
assertNotNull("GroupNames should be not null", user.getGroupNames());
|
||||
assertTrue("UserGroupNames length should be == " + groups.size(),
|
||||
user.getGroupNames().length == groups.size());
|
||||
|
||||
for (String group : user.getGroupNames()) {
|
||||
assertTrue("groupName should be in set ", groups.contains(group));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecurityForNonSecureHadoop() {
|
||||
assertFalse("Security should be disable in non-secure Hadoop",
|
||||
User.isSecurityEnabled());
|
||||
|
||||
Configuration conf = HBaseConfiguration.create();
|
||||
conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
|
||||
conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos");
|
||||
assertTrue("Security should be enabled", User.isHBaseSecurityEnabled(conf));
|
||||
|
||||
conf = HBaseConfiguration.create();
|
||||
conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos");
|
||||
assertFalse("HBase security should not be enabled if "
|
||||
+ User.HBASE_SECURITY_CONF_KEY + " is not set accordingly",
|
||||
User.isHBaseSecurityEnabled(conf));
|
||||
|
||||
conf = HBaseConfiguration.create();
|
||||
conf.set(User.HBASE_SECURITY_CONF_KEY, "kerberos");
|
||||
assertTrue("HBase security should be enabled regardless of underlying "
|
||||
+ "HDFS settings", User.isHBaseSecurityEnabled(conf));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
*
|
||||
* 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.security;
|
||||
|
||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getConfigurationWoPrincipal;
|
||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
|
||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
|
||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getSecuredConfiguration;
|
||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.isKerberosPropertySetted;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hbase.SmallTests;
|
||||
import org.apache.hadoop.security.UserGroupInformation;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
@Category(SmallTests.class)
|
||||
public class TestUsersOperationsWithSecureHadoop {
|
||||
/**
|
||||
* test login with security enabled configuration
|
||||
*
|
||||
* To run this test, we must specify the following system properties:
|
||||
* <p>
|
||||
* <b> hbase.regionserver.kerberos.principal </b>
|
||||
* <p>
|
||||
* <b> hbase.regionserver.keytab.file </b>
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testUserLoginInSecureHadoop() throws Exception {
|
||||
UserGroupInformation defaultLogin = UserGroupInformation.getLoginUser();
|
||||
Configuration conf = getConfigurationWoPrincipal();
|
||||
User.login(conf, HBaseKerberosUtils.KRB_KEYTAB_FILE,
|
||||
HBaseKerberosUtils.KRB_PRINCIPAL, "localhost");
|
||||
|
||||
UserGroupInformation failLogin = UserGroupInformation.getLoginUser();
|
||||
assertTrue("ugi should be the same in case fail login",
|
||||
defaultLogin.equals(failLogin));
|
||||
|
||||
assumeTrue(isKerberosPropertySetted());
|
||||
|
||||
String nnKeyTab = getKeytabFileForTesting();
|
||||
String dnPrincipal = getPrincipalForTesting();
|
||||
|
||||
assertNotNull("KerberosKeytab was not specified", nnKeyTab);
|
||||
assertNotNull("KerberosPrincipal was not specified", dnPrincipal);
|
||||
|
||||
conf = getSecuredConfiguration();
|
||||
UserGroupInformation.setConfiguration(conf);
|
||||
|
||||
User.login(conf, HBaseKerberosUtils.KRB_KEYTAB_FILE,
|
||||
HBaseKerberosUtils.KRB_PRINCIPAL, "localhost");
|
||||
UserGroupInformation successLogin = UserGroupInformation.getLoginUser();
|
||||
assertFalse("ugi should be different in in case success login",
|
||||
defaultLogin.equals(successLogin));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue