HDFS-13682. Cannot create encryption zone after KMS auth token expires.

This commit is contained in:
Xiao Chen 2018-06-20 15:58:01 -07:00
parent b089a06793
commit 32f867a6a9
3 changed files with 41 additions and 6 deletions

View File

@ -32,7 +32,9 @@ import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.ProviderUtils;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
import org.apache.hadoop.security.authentication.client.ConnectionConfigurator;
import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
import org.apache.hadoop.security.ssl.SSLFactory;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
@ -543,7 +545,9 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
String requestMethod = conn.getRequestMethod();
URL url = conn.getURL();
conn = createConnection(url, requestMethod);
conn.setRequestProperty(CONTENT_TYPE, contentType);
if (contentType != null && !contentType.isEmpty()) {
conn.setRequestProperty(CONTENT_TYPE, contentType);
}
return call(conn, jsonOutput, expectedResponse, klass,
authRetryCount - 1);
}
@ -1087,8 +1091,7 @@ public class KMSClientProvider extends KeyProvider implements CryptoExtension,
actualUgi = currentUgi.getRealUser();
}
if (UserGroupInformation.isSecurityEnabled() &&
!containsKmsDt(actualUgi) &&
!actualUgi.hasKerberosCredentials()) {
!containsKmsDt(actualUgi) && !actualUgi.shouldRelogin()) {
// Use login user is only necessary when Kerberos is enabled
// but the actual user does not have either
// Kerberos credential or KMS delegation token for KMS operations

View File

@ -831,7 +831,9 @@ public class UserGroupInformation {
return start + (long) ((end - start) * TICKET_RENEW_WINDOW);
}
private boolean shouldRelogin() {
@InterfaceAudience.Private
@InterfaceStability.Unstable
public boolean shouldRelogin() {
return hasKerberosCredentials() && isHadoopLogin();
}

View File

@ -107,6 +107,8 @@ public class TestSecureEncryptionZoneWithKMS {
// MiniKMS
private static MiniKMS miniKMS;
private final String testKey = "test_key";
private static boolean testKeyCreated = false;
private static final long AUTH_TOKEN_VALIDITY = 1;
// MiniDFS
private MiniDFSCluster cluster;
@ -128,7 +130,7 @@ public class TestSecureEncryptionZoneWithKMS {
}
@Rule
public Timeout timeout = new Timeout(30000);
public Timeout timeout = new Timeout(120000);
@BeforeClass
public static void init() throws Exception {
@ -215,6 +217,9 @@ public class TestSecureEncryptionZoneWithKMS {
"HTTP/localhost");
kmsConf.set("hadoop.kms.authentication.kerberos.name.rules", "DEFAULT");
kmsConf.set("hadoop.kms.acl.GENERATE_EEK", "hdfs");
// set kms auth token expiration low for testCreateZoneAfterAuthTokenExpiry
kmsConf.setLong("hadoop.kms.authentication.token.validity",
AUTH_TOKEN_VALIDITY);
Writer writer = new FileWriter(kmsFile);
kmsConf.writeXml(writer);
@ -260,7 +265,10 @@ public class TestSecureEncryptionZoneWithKMS {
cluster.waitActive();
// Create a test key
DFSTestUtil.createKey(testKey, cluster, conf);
if (!testKeyCreated) {
DFSTestUtil.createKey(testKey, cluster, conf);
testKeyCreated = true;
}
}
@After
@ -307,4 +315,26 @@ public class TestSecureEncryptionZoneWithKMS {
}
});
}
@Test
public void testCreateZoneAfterAuthTokenExpiry() throws Exception {
final UserGroupInformation ugi = UserGroupInformation
.loginUserFromKeytabAndReturnUGI(hdfsPrincipal, keytab);
LOG.info("Created ugi: {} ", ugi);
ugi.doAs((PrivilegedExceptionAction<Object>) () -> {
final Path zone = new Path("/expire1");
fsWrapper.mkdir(zone, FsPermission.getDirDefault(), true);
dfsAdmin.createEncryptionZone(zone, testKey, NO_TRASH);
final Path zone1 = new Path("/expire2");
fsWrapper.mkdir(zone1, FsPermission.getDirDefault(), true);
final long sleepInterval = (AUTH_TOKEN_VALIDITY + 1) * 1000;
LOG.info("Sleeping {} seconds to wait for kms auth token expiration",
sleepInterval);
Thread.sleep(sleepInterval);
dfsAdmin.createEncryptionZone(zone1, testKey, NO_TRASH);
return null;
});
}
}