|
@@ -34,6 +34,7 @@ import org.apache.hadoop.io.Text;
|
|
|
import org.apache.hadoop.minikdc.MiniKdc;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.security.authentication.KerberosTestUtils;
|
|
|
+import org.apache.hadoop.security.authentication.client.AuthenticationException;
|
|
|
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
|
|
|
import org.apache.hadoop.security.authorize.AuthorizationException;
|
|
|
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
|
|
@@ -47,9 +48,9 @@ import org.apache.hadoop.yarn.security.client.TimelineDelegationTokenIdentifier;
|
|
|
import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryServer;
|
|
|
import org.apache.hadoop.yarn.server.timeline.MemoryTimelineStore;
|
|
|
import org.apache.hadoop.yarn.server.timeline.TimelineStore;
|
|
|
-import org.junit.After;
|
|
|
+import org.junit.AfterClass;
|
|
|
import org.junit.Assert;
|
|
|
-import org.junit.Before;
|
|
|
+import org.junit.BeforeClass;
|
|
|
import org.junit.Test;
|
|
|
import org.junit.runner.RunWith;
|
|
|
import org.junit.runners.Parameterized;
|
|
@@ -77,20 +78,19 @@ public class TestTimelineAuthenticationFilter {
|
|
|
return Arrays.asList(new Object[][] { { false }, { true } });
|
|
|
}
|
|
|
|
|
|
- private MiniKdc testMiniKDC;
|
|
|
- private String keystoresDir;
|
|
|
- private String sslConfDir;
|
|
|
- private ApplicationHistoryServer testTimelineServer;
|
|
|
- private Configuration conf;
|
|
|
- private TimelineClient client;
|
|
|
- private boolean withSsl;
|
|
|
+ private static MiniKdc testMiniKDC;
|
|
|
+ private static String keystoresDir;
|
|
|
+ private static String sslConfDir;
|
|
|
+ private static ApplicationHistoryServer testTimelineServer;
|
|
|
+ private static Configuration conf;
|
|
|
+ private static boolean withSsl;
|
|
|
|
|
|
public TestTimelineAuthenticationFilter(boolean withSsl) {
|
|
|
- this.withSsl = withSsl;
|
|
|
+ TestTimelineAuthenticationFilter.withSsl = withSsl;
|
|
|
}
|
|
|
|
|
|
- @Before
|
|
|
- public void setup() {
|
|
|
+ @BeforeClass
|
|
|
+ public static void setup() {
|
|
|
try {
|
|
|
testMiniKDC = new MiniKdc(MiniKdc.createConf(), testRootDir);
|
|
|
testMiniKDC.start();
|
|
@@ -127,6 +127,7 @@ public class TestTimelineAuthenticationFilter {
|
|
|
"localhost:8190");
|
|
|
conf.set("hadoop.proxyuser.HTTP.hosts", "*");
|
|
|
conf.set("hadoop.proxyuser.HTTP.users", FOO_USER);
|
|
|
+ conf.setInt(YarnConfiguration.TIMELINE_SERVICE_CLIENT_MAX_RETRIES, 1);
|
|
|
|
|
|
if (withSsl) {
|
|
|
conf.set(YarnConfiguration.YARN_HTTP_POLICY_KEY,
|
|
@@ -146,14 +147,17 @@ public class TestTimelineAuthenticationFilter {
|
|
|
} catch (Exception e) {
|
|
|
assertTrue("Couldn't setup TimelineServer", false);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- client = TimelineClient.createTimelineClient();
|
|
|
+ private TimelineClient createTimelineClientForUGI() {
|
|
|
+ TimelineClient client = TimelineClient.createTimelineClient();
|
|
|
client.init(conf);
|
|
|
client.start();
|
|
|
+ return client;
|
|
|
}
|
|
|
|
|
|
- @After
|
|
|
- public void tearDown() throws Exception {
|
|
|
+ @AfterClass
|
|
|
+ public static void tearDown() throws Exception {
|
|
|
if (testMiniKDC != null) {
|
|
|
testMiniKDC.stop();
|
|
|
}
|
|
@@ -162,10 +166,6 @@ public class TestTimelineAuthenticationFilter {
|
|
|
testTimelineServer.stop();
|
|
|
}
|
|
|
|
|
|
- if (client != null) {
|
|
|
- client.stop();
|
|
|
- }
|
|
|
-
|
|
|
if (withSsl) {
|
|
|
KeyStoreTestUtil.cleanupSSLConfig(keystoresDir, sslConfDir);
|
|
|
File base = new File(BASEDIR);
|
|
@@ -178,6 +178,7 @@ public class TestTimelineAuthenticationFilter {
|
|
|
KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() {
|
|
|
@Override
|
|
|
public Void call() throws Exception {
|
|
|
+ TimelineClient client = createTimelineClientForUGI();
|
|
|
TimelineEntity entityToStore = new TimelineEntity();
|
|
|
entityToStore.setEntityType(
|
|
|
TestTimelineAuthenticationFilter.class.getName());
|
|
@@ -199,6 +200,7 @@ public class TestTimelineAuthenticationFilter {
|
|
|
KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() {
|
|
|
@Override
|
|
|
public Void call() throws Exception {
|
|
|
+ TimelineClient client = createTimelineClientForUGI();
|
|
|
TimelineDomain domainToStore = new TimelineDomain();
|
|
|
domainToStore.setId(TestTimelineAuthenticationFilter.class.getName());
|
|
|
domainToStore.setReaders("*");
|
|
@@ -215,119 +217,96 @@ public class TestTimelineAuthenticationFilter {
|
|
|
|
|
|
@Test
|
|
|
public void testDelegationTokenOperations() throws Exception {
|
|
|
- KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() {
|
|
|
- @Override
|
|
|
- public Void call() throws Exception {
|
|
|
- // Let HTTP user to get the delegation for itself
|
|
|
- Token<TimelineDelegationTokenIdentifier> token =
|
|
|
- client.getDelegationToken(
|
|
|
- UserGroupInformation.getCurrentUser().getShortUserName());
|
|
|
- Assert.assertNotNull(token);
|
|
|
- TimelineDelegationTokenIdentifier tDT = token.decodeIdentifier();
|
|
|
- Assert.assertNotNull(tDT);
|
|
|
- Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
|
|
+ TimelineClient httpUserClient =
|
|
|
+ KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<TimelineClient>() {
|
|
|
+ @Override
|
|
|
+ public TimelineClient call() throws Exception {
|
|
|
+ return createTimelineClientForUGI();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ UserGroupInformation httpUser =
|
|
|
+ KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<UserGroupInformation>() {
|
|
|
+ @Override
|
|
|
+ public UserGroupInformation call() throws Exception {
|
|
|
+ return UserGroupInformation.getCurrentUser();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // Let HTTP user to get the delegation for itself
|
|
|
+ Token<TimelineDelegationTokenIdentifier> token =
|
|
|
+ httpUserClient.getDelegationToken(httpUser.getShortUserName());
|
|
|
+ Assert.assertNotNull(token);
|
|
|
+ TimelineDelegationTokenIdentifier tDT = token.decodeIdentifier();
|
|
|
+ Assert.assertNotNull(tDT);
|
|
|
+ Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
|
|
|
|
|
- // Renew token
|
|
|
- long renewTime1 = client.renewDelegationToken(token);
|
|
|
- Thread.sleep(100);
|
|
|
- long renewTime2 = client.renewDelegationToken(token);
|
|
|
- Assert.assertTrue(renewTime1 < renewTime2);
|
|
|
+ // Renew token
|
|
|
+ long renewTime1 = httpUserClient.renewDelegationToken(token);
|
|
|
+ Thread.sleep(100);
|
|
|
+ long renewTime2 = httpUserClient.renewDelegationToken(token);
|
|
|
+ Assert.assertTrue(renewTime1 < renewTime2);
|
|
|
|
|
|
- // Cancel token
|
|
|
- client.cancelDelegationToken(token);
|
|
|
- // Renew should not be successful because the token is canceled
|
|
|
- try {
|
|
|
- client.renewDelegationToken(token);
|
|
|
- Assert.fail();
|
|
|
- } catch (Exception e) {
|
|
|
- Assert.assertTrue(e.getMessage().contains(
|
|
|
- "Renewal request for unknown token"));
|
|
|
- }
|
|
|
+ // Cancel token
|
|
|
+ httpUserClient.cancelDelegationToken(token);
|
|
|
+ // Renew should not be successful because the token is canceled
|
|
|
+ try {
|
|
|
+ httpUserClient.renewDelegationToken(token);
|
|
|
+ Assert.fail();
|
|
|
+ } catch (Exception e) {
|
|
|
+ Assert.assertTrue(e.getMessage().contains(
|
|
|
+ "Renewal request for unknown token"));
|
|
|
+ }
|
|
|
|
|
|
- // Let HTTP user to get the delegation token for FOO user
|
|
|
- UserGroupInformation fooUgi = UserGroupInformation.createProxyUser(
|
|
|
- FOO_USER, UserGroupInformation.getCurrentUser());
|
|
|
- token = fooUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() {
|
|
|
+ // Let HTTP user to get the delegation token for FOO user
|
|
|
+ UserGroupInformation fooUgi = UserGroupInformation.createProxyUser(
|
|
|
+ FOO_USER, httpUser);
|
|
|
+ TimelineClient fooUserClient = fooUgi.doAs(
|
|
|
+ new PrivilegedExceptionAction<TimelineClient>() {
|
|
|
@Override
|
|
|
- public Token<TimelineDelegationTokenIdentifier> run()
|
|
|
- throws Exception {
|
|
|
- return client.getDelegationToken(
|
|
|
- UserGroupInformation.getCurrentUser().getShortUserName());
|
|
|
+ public TimelineClient run() throws Exception {
|
|
|
+ return createTimelineClientForUGI();
|
|
|
}
|
|
|
});
|
|
|
- Assert.assertNotNull(token);
|
|
|
- tDT = token.decodeIdentifier();
|
|
|
- Assert.assertNotNull(tDT);
|
|
|
- Assert.assertEquals(new Text(FOO_USER), tDT.getOwner());
|
|
|
- Assert.assertEquals(new Text(HTTP_USER), tDT.getRealUser());
|
|
|
+ token = fooUserClient.getDelegationToken(httpUser.getShortUserName());
|
|
|
+ Assert.assertNotNull(token);
|
|
|
+ tDT = token.decodeIdentifier();
|
|
|
+ Assert.assertNotNull(tDT);
|
|
|
+ Assert.assertEquals(new Text(FOO_USER), tDT.getOwner());
|
|
|
+ Assert.assertEquals(new Text(HTTP_USER), tDT.getRealUser());
|
|
|
|
|
|
- // Renew token
|
|
|
- final Token<TimelineDelegationTokenIdentifier> tokenToRenew = token;
|
|
|
- renewTime1 = fooUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Long>() {
|
|
|
- @Override
|
|
|
- public Long run() throws Exception {
|
|
|
- return client.renewDelegationToken(tokenToRenew);
|
|
|
- }
|
|
|
- });
|
|
|
- renewTime2 = fooUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Long>() {
|
|
|
- @Override
|
|
|
- public Long run() throws Exception {
|
|
|
- return client.renewDelegationToken(tokenToRenew);
|
|
|
- }
|
|
|
- });
|
|
|
- Assert.assertTrue(renewTime1 < renewTime2);
|
|
|
+ // Renew token as the renewer
|
|
|
+ final Token<TimelineDelegationTokenIdentifier> tokenToRenew = token;
|
|
|
+ renewTime1 = httpUserClient.renewDelegationToken(tokenToRenew);
|
|
|
+ renewTime2 = httpUserClient.renewDelegationToken(tokenToRenew);
|
|
|
+ Assert.assertTrue(renewTime1 < renewTime2);
|
|
|
|
|
|
- // Cancel token
|
|
|
- fooUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Void>() {
|
|
|
- @Override
|
|
|
- public Void run() throws Exception {
|
|
|
- client.cancelDelegationToken(tokenToRenew);
|
|
|
- return null;
|
|
|
- }
|
|
|
- });
|
|
|
- // Renew should not be successful because the token is canceled
|
|
|
- try {
|
|
|
- fooUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Void>() {
|
|
|
- @Override
|
|
|
- public Void run() throws Exception {
|
|
|
- client.renewDelegationToken(tokenToRenew);
|
|
|
- return null;
|
|
|
- }
|
|
|
- });
|
|
|
- Assert.fail();
|
|
|
- } catch (Exception e) {
|
|
|
- Assert.assertTrue(e.getMessage().contains(
|
|
|
- "Renewal request for unknown token"));
|
|
|
- }
|
|
|
+ // Cancel token
|
|
|
+ fooUserClient.cancelDelegationToken(tokenToRenew);
|
|
|
+
|
|
|
+ // Renew should not be successful because the token is canceled
|
|
|
+ try {
|
|
|
+ httpUserClient.renewDelegationToken(tokenToRenew);
|
|
|
+ Assert.fail();
|
|
|
+ } catch (Exception e) {
|
|
|
+ Assert.assertTrue(
|
|
|
+ e.getMessage().contains("Renewal request for unknown token"));
|
|
|
+ }
|
|
|
|
|
|
- // Let HTTP user to get the delegation token for BAR user
|
|
|
- UserGroupInformation barUgi = UserGroupInformation.createProxyUser(
|
|
|
- BAR_USER, UserGroupInformation.getCurrentUser());
|
|
|
- token = barUgi.doAs(
|
|
|
- new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() {
|
|
|
+ // Let HTTP user to get the delegation token for BAR user
|
|
|
+ UserGroupInformation barUgi = UserGroupInformation.createProxyUser(
|
|
|
+ BAR_USER, httpUser);
|
|
|
+ TimelineClient barUserClient = barUgi.doAs(
|
|
|
+ new PrivilegedExceptionAction<TimelineClient>() {
|
|
|
@Override
|
|
|
- public Token<TimelineDelegationTokenIdentifier> run()
|
|
|
- throws Exception {
|
|
|
- try {
|
|
|
- Token<TimelineDelegationTokenIdentifier> token =
|
|
|
- client.getDelegationToken(
|
|
|
- UserGroupInformation.getCurrentUser().getShortUserName());
|
|
|
- Assert.fail();
|
|
|
- return token;
|
|
|
- } catch (Exception e) {
|
|
|
- Assert.assertTrue(e instanceof AuthorizationException);
|
|
|
- return null;
|
|
|
- }
|
|
|
+ public TimelineClient run() {
|
|
|
+ return createTimelineClientForUGI();
|
|
|
}
|
|
|
});
|
|
|
- return null;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
|
|
|
+ try {
|
|
|
+ barUserClient.getDelegationToken(httpUser.getShortUserName());
|
|
|
+ Assert.fail();
|
|
|
+ } catch (Exception e) {
|
|
|
+ Assert.assertTrue(e.getCause() instanceof AuthorizationException || e.getCause() instanceof AuthenticationException);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|