YARN-2656. Made RM web services authentication filter support proxy user. Contributed by Varun Vasudev and Zhijie Shen.
(cherry picked from commit 1220bb72d4
)
This commit is contained in:
parent
174138ec26
commit
bec165e163
|
@ -81,7 +81,7 @@ public abstract class DelegationTokenAuthenticationHandler
|
||||||
|
|
||||||
private static final Set<String> DELEGATION_TOKEN_OPS = new HashSet<String>();
|
private static final Set<String> DELEGATION_TOKEN_OPS = new HashSet<String>();
|
||||||
|
|
||||||
static final String DELEGATION_TOKEN_UGI_ATTRIBUTE =
|
public static final String DELEGATION_TOKEN_UGI_ATTRIBUTE =
|
||||||
"hadoop.security.delegation-token.ugi";
|
"hadoop.security.delegation-token.ugi";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -135,6 +135,9 @@ Release 2.6.0 - UNRELEASED
|
||||||
YARN-2501. Enhanced AMRMClient library to support requests against node
|
YARN-2501. Enhanced AMRMClient library to support requests against node
|
||||||
labels. (Wangda Tan via vinodkv)
|
labels. (Wangda Tan via vinodkv)
|
||||||
|
|
||||||
|
YARN-2656. Made RM web services authentication filter support proxy user.
|
||||||
|
(Varun Vasudev and Zhijie Shen via zjshen)
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
|
||||||
YARN-2242. Improve exception information on AM launch crashes. (Li Lu
|
YARN-2242. Improve exception information on AM launch crashes. (Li Lu
|
||||||
|
|
|
@ -18,46 +18,74 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.security.http;
|
package org.apache.hadoop.yarn.server.security.http;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.FilterConfig;
|
import javax.servlet.FilterConfig;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
|
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
|
||||||
|
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticationFilter;
|
||||||
|
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticator;
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
@Unstable
|
@Unstable
|
||||||
public class RMAuthenticationFilter extends AuthenticationFilter {
|
public class RMAuthenticationFilter extends
|
||||||
|
DelegationTokenAuthenticationFilter {
|
||||||
|
|
||||||
|
static private AbstractDelegationTokenSecretManager<?> manager;
|
||||||
public static final String AUTH_HANDLER_PROPERTY =
|
public static final String AUTH_HANDLER_PROPERTY =
|
||||||
"yarn.resourcemanager.authentication-handler";
|
"yarn.resourcemanager.authentication-handler";
|
||||||
|
private static final String OLD_HEADER = "Hadoop-YARN-Auth-Delegation-Token";
|
||||||
|
|
||||||
public RMAuthenticationFilter() {
|
public RMAuthenticationFilter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Properties getConfiguration(String configPrefix,
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
FilterConfig filterConfig) throws ServletException {
|
filterConfig.getServletContext().setAttribute(
|
||||||
|
DelegationTokenAuthenticationFilter.DELEGATION_TOKEN_SECRET_MANAGER_ATTR,
|
||||||
// In yarn-site.xml, we can simply set type to "kerberos". However, we need
|
manager);
|
||||||
// to replace the name here to use the customized Kerberos + DT service
|
super.init(filterConfig);
|
||||||
// instead of the standard Kerberos handler.
|
|
||||||
|
|
||||||
Properties properties = super.getConfiguration(configPrefix, filterConfig);
|
|
||||||
String yarnAuthHandler = properties.getProperty(AUTH_HANDLER_PROPERTY);
|
|
||||||
if (yarnAuthHandler == null || yarnAuthHandler.isEmpty()) {
|
|
||||||
// if http auth type is simple, the default authentication filter
|
|
||||||
// will handle it, else throw an exception
|
|
||||||
if (!properties.getProperty(AUTH_TYPE).equals("simple")) {
|
|
||||||
throw new ServletException("Authentication handler class is empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (properties.getProperty(AUTH_TYPE).equalsIgnoreCase("kerberos")) {
|
|
||||||
properties.setProperty(AUTH_TYPE, yarnAuthHandler);
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response,
|
||||||
|
FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
HttpServletRequest req = (HttpServletRequest) request;
|
||||||
|
String newHeader =
|
||||||
|
req.getHeader(DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER);
|
||||||
|
if (newHeader == null || newHeader.isEmpty()) {
|
||||||
|
// For backward compatibility, allow use of the old header field
|
||||||
|
// only when the new header doesn't exist
|
||||||
|
final String oldHeader = req.getHeader(OLD_HEADER);
|
||||||
|
if (oldHeader != null && !oldHeader.isEmpty()) {
|
||||||
|
request = new HttpServletRequestWrapper(req) {
|
||||||
|
@Override
|
||||||
|
public String getHeader(String name) {
|
||||||
|
if (name
|
||||||
|
.equals(DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER)) {
|
||||||
|
return oldHeader;
|
||||||
|
}
|
||||||
|
return super.getHeader(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.doFilter(request, response, filterChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDelegationTokenSecretManager(
|
||||||
|
AbstractDelegationTokenSecretManager<?> manager) {
|
||||||
|
RMAuthenticationFilter.manager = manager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,17 +35,21 @@ import org.apache.hadoop.security.SecurityUtil;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
|
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
|
||||||
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
|
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
|
||||||
|
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticationHandler;
|
||||||
|
import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
|
||||||
|
|
||||||
@Unstable
|
@Unstable
|
||||||
public class RMAuthenticationFilterInitializer extends FilterInitializer {
|
public class RMAuthenticationFilterInitializer extends FilterInitializer {
|
||||||
|
|
||||||
String configPrefix;
|
String configPrefix;
|
||||||
|
String proxyPrefix;
|
||||||
String signatureSecretFileProperty;
|
String signatureSecretFileProperty;
|
||||||
String kerberosPrincipalProperty;
|
String kerberosPrincipalProperty;
|
||||||
String cookiePath;
|
String cookiePath;
|
||||||
|
|
||||||
public RMAuthenticationFilterInitializer() {
|
public RMAuthenticationFilterInitializer() {
|
||||||
this.configPrefix = "hadoop.http.authentication.";
|
this.configPrefix = "hadoop.http.authentication.";
|
||||||
|
this.proxyPrefix = "yarn.resourcemanager.webapp.proxyuser.";
|
||||||
this.signatureSecretFileProperty =
|
this.signatureSecretFileProperty =
|
||||||
AuthenticationFilter.SIGNATURE_SECRET + ".file";
|
AuthenticationFilter.SIGNATURE_SECRET + ".file";
|
||||||
this.kerberosPrincipalProperty = KerberosAuthenticationHandler.PRINCIPAL;
|
this.kerberosPrincipalProperty = KerberosAuthenticationHandler.PRINCIPAL;
|
||||||
|
@ -59,10 +63,14 @@ public class RMAuthenticationFilterInitializer extends FilterInitializer {
|
||||||
filterConfig.put(AuthenticationFilter.COOKIE_PATH, cookiePath);
|
filterConfig.put(AuthenticationFilter.COOKIE_PATH, cookiePath);
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : conf) {
|
for (Map.Entry<String, String> entry : conf) {
|
||||||
String name = entry.getKey();
|
String propName = entry.getKey();
|
||||||
if (name.startsWith(configPrefix)) {
|
if (propName.startsWith(configPrefix)) {
|
||||||
String value = conf.get(name);
|
String value = conf.get(propName);
|
||||||
name = name.substring(configPrefix.length());
|
String name = propName.substring(configPrefix.length());
|
||||||
|
filterConfig.put(name, value);
|
||||||
|
} else if (propName.startsWith(proxyPrefix)) {
|
||||||
|
String value = conf.get(propName);
|
||||||
|
String name = propName.substring("yarn.resourcemanager.webapp.".length());
|
||||||
filterConfig.put(name, value);
|
filterConfig.put(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,6 +115,10 @@ public class RMAuthenticationFilterInitializer extends FilterInitializer {
|
||||||
}
|
}
|
||||||
filterConfig.put(KerberosAuthenticationHandler.PRINCIPAL, principal);
|
filterConfig.put(KerberosAuthenticationHandler.PRINCIPAL, principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filterConfig.put(DelegationTokenAuthenticationHandler.TOKEN_KIND,
|
||||||
|
RMDelegationTokenIdentifier.KIND_NAME.toString());
|
||||||
|
|
||||||
return filterConfig;
|
return filterConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -901,6 +901,8 @@ public class ResourceManager extends CompositeService implements Recoverable {
|
||||||
+ " for RM webapp authentication");
|
+ " for RM webapp authentication");
|
||||||
RMAuthenticationHandler
|
RMAuthenticationHandler
|
||||||
.setSecretManager(getClientRMService().rmDTSecretManager);
|
.setSecretManager(getClientRMService().rmDTSecretManager);
|
||||||
|
RMAuthenticationFilter
|
||||||
|
.setDelegationTokenSecretManager(getClientRMService().rmDTSecretManager);
|
||||||
String yarnAuthKey =
|
String yarnAuthKey =
|
||||||
authPrefix + RMAuthenticationFilter.AUTH_HANDLER_PROPERTY;
|
authPrefix + RMAuthenticationFilter.AUTH_HANDLER_PROPERTY;
|
||||||
conf.setStrings(yarnAuthKey, RMAuthenticationHandler.class.getName());
|
conf.setStrings(yarnAuthKey, RMAuthenticationHandler.class.getName());
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHa
|
||||||
import org.apache.hadoop.security.authorize.AuthorizationException;
|
import org.apache.hadoop.security.authorize.AuthorizationException;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
import org.apache.hadoop.security.token.TokenIdentifier;
|
||||||
|
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticationHandler;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
|
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationRequest;
|
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationRequest;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse;
|
import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationResponse;
|
||||||
|
@ -1085,10 +1086,18 @@ public class RMWebServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
String authType = hsr.getAuthType();
|
String authType = hsr.getAuthType();
|
||||||
if (!KerberosAuthenticationHandler.TYPE.equals(authType)) {
|
if (!KerberosAuthenticationHandler.TYPE.equalsIgnoreCase(authType)) {
|
||||||
String msg =
|
String msg =
|
||||||
"Delegation token operations can only be carried out on a "
|
"Delegation token operations can only be carried out on a "
|
||||||
+ "Kerberos authenticated channel";
|
+ "Kerberos authenticated channel. Expected auth type is "
|
||||||
|
+ KerberosAuthenticationHandler.TYPE + ", got type " + authType;
|
||||||
|
throw new YarnException(msg);
|
||||||
|
}
|
||||||
|
if (hsr
|
||||||
|
.getAttribute(DelegationTokenAuthenticationHandler.DELEGATION_TOKEN_UGI_ATTRIBUTE) != null) {
|
||||||
|
String msg =
|
||||||
|
"Delegation token operations cannot be carried out using delegation"
|
||||||
|
+ " token authentication.";
|
||||||
throw new YarnException(msg);
|
throw new YarnException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -708,6 +708,7 @@ public class TestRMAdminService {
|
||||||
aclsString);
|
aclsString);
|
||||||
|
|
||||||
// verify ProxyUsers and ProxyHosts
|
// verify ProxyUsers and ProxyHosts
|
||||||
|
ProxyUsers.refreshSuperUserGroupsConfiguration(configuration);
|
||||||
Assert.assertTrue(ProxyUsers.getDefaultImpersonationProvider().getProxyGroups()
|
Assert.assertTrue(ProxyUsers.getDefaultImpersonationProvider().getProxyGroups()
|
||||||
.get("hadoop.proxyuser.test.groups").size() == 1);
|
.get("hadoop.proxyuser.test.groups").size() == 1);
|
||||||
Assert.assertTrue(ProxyUsers.getDefaultImpersonationProvider().getProxyGroups()
|
Assert.assertTrue(ProxyUsers.getDefaultImpersonationProvider().getProxyGroups()
|
||||||
|
|
|
@ -31,6 +31,8 @@ import java.io.OutputStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
@ -46,7 +48,10 @@ import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.authentication.KerberosTestUtils;
|
import org.apache.hadoop.security.authentication.KerberosTestUtils;
|
||||||
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
|
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
|
||||||
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
|
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
|
||||||
|
import org.apache.hadoop.security.token.Token;
|
||||||
|
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticator;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
|
import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||||
|
@ -55,11 +60,15 @@ import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationSubmi
|
||||||
import org.apache.hadoop.yarn.util.ConverterUtils;
|
import org.apache.hadoop.yarn.util.ConverterUtils;
|
||||||
import org.codehaus.jettison.json.JSONObject;
|
import org.codehaus.jettison.json.JSONObject;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.sun.jersey.api.client.ClientResponse.Status;
|
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
public class TestRMWebServicesDelegationTokenAuthentication {
|
public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
|
|
||||||
private static final File testRootDir = new File("target",
|
private static final File testRootDir = new File("target",
|
||||||
|
@ -74,10 +83,17 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
private static MiniKdc testMiniKDC;
|
private static MiniKdc testMiniKDC;
|
||||||
private static MockRM rm;
|
private static MockRM rm;
|
||||||
|
|
||||||
|
|
||||||
|
String delegationTokenHeader;
|
||||||
|
|
||||||
// use published header name
|
// use published header name
|
||||||
final static String DelegationTokenHeader =
|
final static String OldDelegationTokenHeader =
|
||||||
"Hadoop-YARN-Auth-Delegation-Token";
|
"Hadoop-YARN-Auth-Delegation-Token";
|
||||||
|
|
||||||
|
// alternate header name
|
||||||
|
final static String NewDelegationTokenHeader =
|
||||||
|
DelegationTokenAuthenticator.DELEGATION_TOKEN_HEADER;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
try {
|
try {
|
||||||
|
@ -99,8 +115,14 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestRMWebServicesDelegationTokenAuthentication() throws Exception {
|
@Parameterized.Parameters
|
||||||
|
public static Collection<Object[]> headers() {
|
||||||
|
return Arrays.asList(new Object[][] { {OldDelegationTokenHeader}, {NewDelegationTokenHeader}});
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestRMWebServicesDelegationTokenAuthentication(String header) throws Exception {
|
||||||
super();
|
super();
|
||||||
|
this.delegationTokenHeader = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupAndStartRM() throws Exception {
|
private static void setupAndStartRM() throws Exception {
|
||||||
|
@ -136,6 +158,8 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
rmconf.set(YarnConfiguration.NM_WEBAPP_SPNEGO_KEYTAB_FILE_KEY,
|
rmconf.set(YarnConfiguration.NM_WEBAPP_SPNEGO_KEYTAB_FILE_KEY,
|
||||||
httpSpnegoKeytabFile.getAbsolutePath());
|
httpSpnegoKeytabFile.getAbsolutePath());
|
||||||
rmconf.setBoolean("mockrm.webapp.enabled", true);
|
rmconf.setBoolean("mockrm.webapp.enabled", true);
|
||||||
|
rmconf.set("yarn.resourcemanager.webapp.proxyuser.client.hosts", "*");
|
||||||
|
rmconf.set("yarn.resourcemanager.webapp.proxyuser.client.groups", "*");
|
||||||
UserGroupInformation.setConfiguration(rmconf);
|
UserGroupInformation.setConfiguration(rmconf);
|
||||||
rm = new MockRM(rmconf);
|
rm = new MockRM(rmconf);
|
||||||
rm.start();
|
rm.start();
|
||||||
|
@ -143,10 +167,11 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupKDC() throws Exception {
|
private static void setupKDC() throws Exception {
|
||||||
if (miniKDCStarted == false) {
|
if (!miniKDCStarted) {
|
||||||
testMiniKDC.start();
|
testMiniKDC.start();
|
||||||
getKdc().createPrincipal(httpSpnegoKeytabFile, "HTTP/localhost",
|
getKdc().createPrincipal(httpSpnegoKeytabFile, "HTTP/localhost",
|
||||||
"client", UserGroupInformation.getLoginUser().getShortUserName());
|
"client", UserGroupInformation.getLoginUser().getShortUserName(),
|
||||||
|
"client2");
|
||||||
miniKDCStarted = true;
|
miniKDCStarted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,11 +214,26 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = (HttpURLConnection) url.openConnection();
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestProperty(DelegationTokenHeader, token);
|
conn.setRequestProperty(delegationTokenHeader, token);
|
||||||
setupConn(conn, "POST", MediaType.APPLICATION_XML, requestBody);
|
setupConn(conn, "POST", MediaType.APPLICATION_XML, requestBody);
|
||||||
|
|
||||||
// this should not fail
|
// this should not fail
|
||||||
conn.getInputStream();
|
try {
|
||||||
|
conn.getInputStream();
|
||||||
|
}
|
||||||
|
catch(IOException ie) {
|
||||||
|
InputStream errorStream = conn.getErrorStream();
|
||||||
|
String error = "";
|
||||||
|
BufferedReader reader = null;
|
||||||
|
reader = new BufferedReader(new InputStreamReader(errorStream, "UTF8"));
|
||||||
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
|
error += line;
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
errorStream.close();
|
||||||
|
fail("Response " + conn.getResponseCode() + "; " + error);
|
||||||
|
}
|
||||||
|
|
||||||
boolean appExists =
|
boolean appExists =
|
||||||
rm.getRMContext().getRMApps()
|
rm.getRMContext().getRMApps()
|
||||||
.containsKey(ConverterUtils.toApplicationId(appid));
|
.containsKey(ConverterUtils.toApplicationId(appid));
|
||||||
|
@ -203,8 +243,6 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
.get(ConverterUtils.toApplicationId(appid));
|
.get(ConverterUtils.toApplicationId(appid));
|
||||||
String owner = actualApp.getUser();
|
String owner = actualApp.getUser();
|
||||||
assertEquals("client", owner);
|
assertEquals("client", owner);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to make sure that cancelled delegation tokens
|
// Test to make sure that cancelled delegation tokens
|
||||||
|
@ -221,7 +259,7 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
|
|
||||||
URL url = new URL("http://localhost:8088/ws/v1/cluster/apps");
|
URL url = new URL("http://localhost:8088/ws/v1/cluster/apps");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestProperty(DelegationTokenHeader, token);
|
conn.setRequestProperty(delegationTokenHeader, token);
|
||||||
setupConn(conn, "POST", MediaType.APPLICATION_XML, requestBody);
|
setupConn(conn, "POST", MediaType.APPLICATION_XML, requestBody);
|
||||||
|
|
||||||
// this should fail with unauthorized because only
|
// this should fail with unauthorized because only
|
||||||
|
@ -232,7 +270,6 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test to make sure that we can't do delegation token
|
// Test to make sure that we can't do delegation token
|
||||||
|
@ -248,7 +285,7 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
for (String requestBody : requests) {
|
for (String requestBody : requests) {
|
||||||
URL url = new URL("http://localhost:8088/ws/v1/cluster/delegation-token");
|
URL url = new URL("http://localhost:8088/ws/v1/cluster/delegation-token");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestProperty(DelegationTokenHeader, token);
|
conn.setRequestProperty(delegationTokenHeader, token);
|
||||||
setupConn(conn, "POST", MediaType.APPLICATION_JSON, requestBody);
|
setupConn(conn, "POST", MediaType.APPLICATION_JSON, requestBody);
|
||||||
try {
|
try {
|
||||||
conn.getInputStream();
|
conn.getInputStream();
|
||||||
|
@ -262,7 +299,7 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
// test cancel
|
// test cancel
|
||||||
URL url = new URL("http://localhost:8088/ws/v1/cluster/delegation-token");
|
URL url = new URL("http://localhost:8088/ws/v1/cluster/delegation-token");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestProperty(DelegationTokenHeader, token);
|
conn.setRequestProperty(delegationTokenHeader, token);
|
||||||
conn.setRequestProperty(RMWebServices.DELEGATION_TOKEN_HEADER, token);
|
conn.setRequestProperty(RMWebServices.DELEGATION_TOKEN_HEADER, token);
|
||||||
setupConn(conn, "DELETE", null, null);
|
setupConn(conn, "DELETE", null, null);
|
||||||
try {
|
try {
|
||||||
|
@ -271,11 +308,94 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
||||||
}
|
}
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
// Superuser "client" should be able to get a delegation token
|
||||||
|
// for user "client2" when authenticated using Kerberos
|
||||||
|
// The request shouldn't work when authenticated using DelegationTokens
|
||||||
|
@Test
|
||||||
|
public void testDoAs() throws Exception {
|
||||||
|
|
||||||
|
KerberosTestUtils.doAsClient(new Callable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
String token = "";
|
||||||
|
String owner = "";
|
||||||
|
String renewer = "renewer";
|
||||||
|
String body = "{\"renewer\":\"" + renewer + "\"}";
|
||||||
|
URL url =
|
||||||
|
new URL("http://localhost:8088/ws/v1/cluster/delegation-token?doAs=client2");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
setupConn(conn, "POST", MediaType.APPLICATION_JSON, body);
|
||||||
|
InputStream response = conn.getInputStream();
|
||||||
|
assertEquals(Status.OK.getStatusCode(), conn.getResponseCode());
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(response, "UTF8"));
|
||||||
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
|
JSONObject obj = new JSONObject(line);
|
||||||
|
if (obj.has("token")) {
|
||||||
|
token = obj.getString("token");
|
||||||
|
}
|
||||||
|
if(obj.has("owner")) {
|
||||||
|
owner = obj.getString("owner");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(reader);
|
||||||
|
IOUtils.closeQuietly(response);
|
||||||
|
}
|
||||||
|
Assert.assertEquals("client2", owner);
|
||||||
|
Token<RMDelegationTokenIdentifier> realToken = new Token<RMDelegationTokenIdentifier>();
|
||||||
|
realToken.decodeFromUrlString(token);
|
||||||
|
Assert.assertEquals("client2", realToken.decodeIdentifier().getOwner().toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// this should not work
|
||||||
|
final String token = getDelegationToken("client");
|
||||||
|
String renewer = "renewer";
|
||||||
|
String body = "{\"renewer\":\"" + renewer + "\"}";
|
||||||
|
URL url =
|
||||||
|
new URL("http://localhost:8088/ws/v1/cluster/delegation-token?doAs=client2");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestProperty(delegationTokenHeader, token);
|
||||||
|
setupConn(conn, "POST", MediaType.APPLICATION_JSON, body);
|
||||||
|
try {
|
||||||
|
conn.getInputStream();
|
||||||
|
fail("Client should not be allowed to impersonate using delegation tokens");
|
||||||
|
}
|
||||||
|
catch(IOException ie) {
|
||||||
|
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should also fail due to client2 not being a super user
|
||||||
|
KerberosTestUtils.doAs("client2@EXAMPLE.COM", new Callable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
String renewer = "renewer";
|
||||||
|
String body = "{\"renewer\":\"" + renewer + "\"}";
|
||||||
|
URL url =
|
||||||
|
new URL(
|
||||||
|
"http://localhost:8088/ws/v1/cluster/delegation-token?doAs=client");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
setupConn(conn, "POST", MediaType.APPLICATION_JSON, body);
|
||||||
|
try {
|
||||||
|
conn.getInputStream();
|
||||||
|
fail("Non superuser client should not be allowed to carry out doAs");
|
||||||
|
}
|
||||||
|
catch (IOException ie) {
|
||||||
|
assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDelegationToken(final String renewer) throws Exception {
|
private String getDelegationToken(final String renewer) throws Exception {
|
||||||
String token = KerberosTestUtils.doAsClient(new Callable<String>() {
|
return KerberosTestUtils.doAsClient(new Callable<String>() {
|
||||||
@Override
|
@Override
|
||||||
public String call() throws Exception {
|
public String call() throws Exception {
|
||||||
String ret = null;
|
String ret = null;
|
||||||
|
@ -305,7 +425,6 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelDelegationToken(final String tokenString) throws Exception {
|
private void cancelDelegationToken(final String tokenString) throws Exception {
|
||||||
|
@ -325,7 +444,6 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getMarshalledAppInfo(ApplicationSubmissionContextInfo appInfo)
|
static String getMarshalledAppInfo(ApplicationSubmissionContextInfo appInfo)
|
||||||
|
@ -353,5 +471,4 @@ public class TestRMWebServicesDelegationTokenAuthentication {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2943,7 +2943,7 @@ Accept: application/xml
|
||||||
|
|
||||||
+---+
|
+---+
|
||||||
PUT http://<rm http address:port>/ws/v1/cluster/apps/application_1399397633663_0003/state
|
PUT http://<rm http address:port>/ws/v1/cluster/apps/application_1399397633663_0003/state
|
||||||
Hadoop-YARN-Auth-Delegation-Token: MgASY2xpZW50QEVYQU1QTEUuQ09NDHRlc3QtcmVuZXdlcgCKAUbjqcHHigFHB7ZFxwQCFKWD3znCkDSy6SQIjRCLDydxbxvgE1JNX0RFTEVHQVRJT05fVE9LRU4A
|
X-Hadoop-Delegation-Token: MgASY2xpZW50QEVYQU1QTEUuQ09NDHRlc3QtcmVuZXdlcgCKAUbjqcHHigFHB7ZFxwQCFKWD3znCkDSy6SQIjRCLDydxbxvgE1JNX0RFTEVHQVRJT05fVE9LRU4A
|
||||||
Content-Type: application/json; charset=UTF8
|
Content-Type: application/json; charset=UTF8
|
||||||
{
|
{
|
||||||
"state":"KILLED"
|
"state":"KILLED"
|
||||||
|
|
Loading…
Reference in New Issue