HADOOP-15997. KMS client uses wrong UGI after HADOOP-14445. Contributed by Wei-Chiu Chuang.

(cherry picked from commit 51427cbdfb)
This commit is contained in:
Sunil G 2019-01-04 21:49:06 +05:30
parent e8e55839a0
commit d3fdbbc2ab
2 changed files with 51 additions and 7 deletions

View File

@ -1147,17 +1147,16 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
// Add existing credentials from the UGI, since provider is cached. // Add existing credentials from the UGI, since provider is cached.
Credentials creds = ugi.getCredentials(); Credentials creds = ugi.getCredentials();
if (!creds.getAllTokens().isEmpty()) { if (!creds.getAllTokens().isEmpty()) {
LOG.debug("Searching for token that matches service: {}", dtService); LOG.debug("Searching for KMS delegation token in user {}'s credentials",
org.apache.hadoop.security.token.Token<? extends TokenIdentifier> ugi);
dToken = creds.getToken(dtService); return clientTokenProvider.selectDelegationToken(creds) != null;
if (dToken != null) {
return true;
}
} }
return false; return false;
} }
private UserGroupInformation getActualUgi() throws IOException { @VisibleForTesting
UserGroupInformation getActualUgi() throws IOException {
final UserGroupInformation currentUgi = UserGroupInformation final UserGroupInformation currentUgi = UserGroupInformation
.getCurrentUser(); .getCurrentUser();

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.crypto.key.kms; package org.apache.hadoop.crypto.key.kms;
import static org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion; import static org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
import static org.apache.hadoop.crypto.key.kms.KMSDelegationToken.TOKEN_KIND;
import static org.apache.hadoop.test.LambdaTestUtils.intercept; import static org.apache.hadoop.test.LambdaTestUtils.intercept;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
@ -35,6 +36,7 @@ import java.net.URI;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -45,11 +47,15 @@ import org.apache.hadoop.crypto.key.KeyProvider;
import org.apache.hadoop.crypto.key.KeyProvider.Options; import org.apache.hadoop.crypto.key.KeyProvider.Options;
import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension; import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.ConnectTimeoutException; import org.apache.hadoop.net.ConnectTimeoutException;
import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.security.token.Token;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -909,4 +915,43 @@ public class TestLoadBalancingKMSClientProvider {
assertNotEquals(kmsUri, providers[i].getCanonicalServiceName()); assertNotEquals(kmsUri, providers[i].getCanonicalServiceName());
} }
} }
@Test
public void testGetActualUGI() throws Exception {
// enable security
final Configuration conf = new Configuration();
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation ugi = UserGroupInformation.createUserForTesting(
"foo", new String[] {"hadoop"});
String providerUriString = "kms://http@host1;host2;host3:9600/kms/foo";
final URI kmsUri = URI.create(providerUriString);
// create a fake kms dt
final Token token = new Token();
token.setKind(TOKEN_KIND);
token.setService(new Text(providerUriString));
// call getActualUgi() with the current user.
UserGroupInformation actualUgi =
ugi.doAs(new PrivilegedExceptionAction<UserGroupInformation>(){
@Override
public UserGroupInformation run() throws Exception {
final KeyProvider kp =
new KMSClientProvider.Factory().createProvider(kmsUri, conf);
final LoadBalancingKMSClientProvider lbkp =
(LoadBalancingKMSClientProvider) kp;
final Credentials creds = new Credentials();
creds.addToken(token.getService(), token);
UserGroupInformation.getCurrentUser().addCredentials(creds);
KMSClientProvider[] providers = lbkp.getProviders();
return providers[0].getActualUgi();
}
});
// make sure getActualUgi() returns the current user, not login user.
assertEquals(
"getActualUgi() should return the current user, not login user",
ugi, actualUgi);
}
} }