HADOOP-13749. KMSClientProvider combined with KeyProviderCache can result in wrong UGI being used. Contributed by Xiaoyu Yao.

(cherry picked from commit d0a347984d)
This commit is contained in:
Xiaoyu Yao 2016-10-23 10:58:36 -07:00
parent 68d91e0200
commit 48c9064b33
3 changed files with 42 additions and 26 deletions

View File

@ -373,7 +373,6 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
private ConnectionConfigurator configurator; private ConnectionConfigurator configurator;
private DelegationTokenAuthenticatedURL.Token authToken; private DelegationTokenAuthenticatedURL.Token authToken;
private final int authRetry; private final int authRetry;
private final UserGroupInformation actualUgi;
@Override @Override
public String toString() { public String toString() {
@ -455,15 +454,6 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
KMS_CLIENT_ENC_KEY_CACHE_NUM_REFILL_THREADS_DEFAULT), KMS_CLIENT_ENC_KEY_CACHE_NUM_REFILL_THREADS_DEFAULT),
new EncryptedQueueRefiller()); new EncryptedQueueRefiller());
authToken = new DelegationTokenAuthenticatedURL.Token(); authToken = new DelegationTokenAuthenticatedURL.Token();
UserGroupInformation.AuthenticationMethod authMethod =
UserGroupInformation.getCurrentUser().getAuthenticationMethod();
if (authMethod == UserGroupInformation.AuthenticationMethod.PROXY) {
actualUgi = UserGroupInformation.getCurrentUser().getRealUser();
} else if (authMethod == UserGroupInformation.AuthenticationMethod.TOKEN) {
actualUgi = UserGroupInformation.getLoginUser();
} else {
actualUgi =UserGroupInformation.getCurrentUser();
}
} }
private static Path extractKMSPath(URI uri) throws MalformedURLException, IOException { private static Path extractKMSPath(URI uri) throws MalformedURLException, IOException {
@ -530,19 +520,9 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
throws IOException { throws IOException {
HttpURLConnection conn; HttpURLConnection conn;
try { try {
// if current UGI is different from UGI at constructor time, behave as final String doAsUser = getDoAsUser();
// proxyuser conn = getActualUgi().doAs(new PrivilegedExceptionAction
UserGroupInformation currentUgi = UserGroupInformation.getCurrentUser(); <HttpURLConnection>() {
final String doAsUser = (currentUgi.getAuthenticationMethod() ==
UserGroupInformation.AuthenticationMethod.PROXY)
? currentUgi.getShortUserName() : null;
// If current UGI contains kms-dt && is not proxy, doAs it to use its dt.
// Otherwise, create the HTTP connection using the UGI at constructor time
UserGroupInformation ugiToUse =
(currentUgiContainsKmsDt() && doAsUser == null) ?
currentUgi : actualUgi;
conn = ugiToUse.doAs(new PrivilegedExceptionAction<HttpURLConnection>() {
@Override @Override
public HttpURLConnection run() throws Exception { public HttpURLConnection run() throws Exception {
DelegationTokenAuthenticatedURL authUrl = DelegationTokenAuthenticatedURL authUrl =
@ -919,7 +899,7 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
token, url, doAsUser); token, url, doAsUser);
final DelegationTokenAuthenticatedURL authUrl = final DelegationTokenAuthenticatedURL authUrl =
new DelegationTokenAuthenticatedURL(configurator); new DelegationTokenAuthenticatedURL(configurator);
return actualUgi.doAs( return getActualUgi().doAs(
new PrivilegedExceptionAction<Long>() { new PrivilegedExceptionAction<Long>() {
@Override @Override
public Long run() throws Exception { public Long run() throws Exception {
@ -942,7 +922,7 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
final String doAsUser = getDoAsUser(); final String doAsUser = getDoAsUser();
final DelegationTokenAuthenticatedURL.Token token = final DelegationTokenAuthenticatedURL.Token token =
generateDelegationToken(dToken); generateDelegationToken(dToken);
return actualUgi.doAs( return getActualUgi().doAs(
new PrivilegedExceptionAction<Void>() { new PrivilegedExceptionAction<Void>() {
@Override @Override
public Void run() throws Exception { public Void run() throws Exception {
@ -1014,7 +994,7 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
new DelegationTokenAuthenticatedURL(configurator); new DelegationTokenAuthenticatedURL(configurator);
try { try {
final String doAsUser = getDoAsUser(); final String doAsUser = getDoAsUser();
token = actualUgi.doAs(new PrivilegedExceptionAction<Token<?>>() { token = getActualUgi().doAs(new PrivilegedExceptionAction<Token<?>>() {
@Override @Override
public Token<?> run() throws Exception { public Token<?> run() throws Exception {
// Not using the cached token here.. Creating a new token here // Not using the cached token here.. Creating a new token here
@ -1060,6 +1040,26 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
return false; return false;
} }
private UserGroupInformation getActualUgi() throws IOException {
final UserGroupInformation currentUgi = UserGroupInformation
.getCurrentUser();
if (LOG.isDebugEnabled()) {
UserGroupInformation.logAllUserInfo(currentUgi);
}
// Use current user by default
UserGroupInformation actualUgi = currentUgi;
if (currentUgi.getRealUser() != null) {
// Use real user for proxy user
actualUgi = currentUgi.getRealUser();
} else if (!currentUgiContainsKmsDt() &&
!currentUgi.hasKerberosCredentials()) {
// Use login user for user that does not have either
// Kerberos credential or KMS delegation token for KMS operations
actualUgi = currentUgi.getLoginUser();
}
return actualUgi;
}
/** /**
* Shutdown valueQueue executor threads * Shutdown valueQueue executor threads
*/ */

View File

@ -1811,6 +1811,20 @@ public class UserGroupInformation {
} }
} }
public static void logAllUserInfo(UserGroupInformation ugi) throws
IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("UGI: " + ugi);
if (ugi.getRealUser() != null) {
LOG.debug("+RealUGI: " + ugi.getRealUser());
}
LOG.debug("+LoginUGI: " + ugi.getLoginUser());
for (Token<?> token : ugi.getTokens()) {
LOG.debug("+UGI token:" + token);
}
}
}
private void print() throws IOException { private void print() throws IOException {
System.out.println("User: " + getUserName()); System.out.println("User: " + getUserName());
System.out.print("Group Ids: "); System.out.print("Group Ids: ");

View File

@ -1832,6 +1832,7 @@ public class TestKMS {
} else { } else {
otherUgi = UserGroupInformation.createUserForTesting("client1", otherUgi = UserGroupInformation.createUserForTesting("client1",
new String[] {"other group"}); new String[] {"other group"});
UserGroupInformation.setLoginUser(otherUgi);
} }
try { try {
// test delegation token renewal via renewer // test delegation token renewal via renewer
@ -2152,6 +2153,7 @@ public class TestKMS {
loginUserFromKeytabAndReturnUGI("client", keytab.getAbsolutePath()); loginUserFromKeytabAndReturnUGI("client", keytab.getAbsolutePath());
} else { } else {
proxyUgi = UserGroupInformation.createRemoteUser("client"); proxyUgi = UserGroupInformation.createRemoteUser("client");
UserGroupInformation.setLoginUser(proxyUgi);
} }
final UserGroupInformation clientUgi = proxyUgi; final UserGroupInformation clientUgi = proxyUgi;