diff --git a/hadoop-common-project/hadoop-auth/pom.xml b/hadoop-common-project/hadoop-auth/pom.xml
index 2ff51d6ffee..564518c540b 100644
--- a/hadoop-common-project/hadoop-auth/pom.xml
+++ b/hadoop-common-project/hadoop-auth/pom.xml
@@ -61,6 +61,16 @@
org.mortbay.jetty
jetty
test
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ test
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-logging-juli
+ test
javax.servlet
diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
index 316cd60a256..9330444c46e 100644
--- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
@@ -519,9 +519,7 @@ public class AuthenticationFilter implements Filter {
StringBuilder sb = new StringBuilder(AuthenticatedURL.AUTH_COOKIE)
.append("=");
if (token != null && token.length() > 0) {
- sb.append("\"")
- .append(token)
- .append("\"");
+ sb.append(token);
}
sb.append("; Version=1");
diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java
index 4e4ecc483eb..8f35e13e66a 100644
--- a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java
+++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java
@@ -13,7 +13,22 @@
*/
package org.apache.hadoop.security.authentication.client;
+import org.apache.catalina.deploy.FilterDef;
+import org.apache.catalina.deploy.FilterMap;
+import org.apache.catalina.startup.Tomcat;
import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.params.AuthPolicy;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
+import org.apache.http.impl.client.SystemDefaultHttpClient;
+import org.apache.http.util.EntityUtils;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.FilterHolder;
@@ -24,16 +39,19 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.ServerSocket;
import java.net.URL;
+import java.security.Principal;
import java.util.Properties;
import org.junit.Assert;
@@ -41,10 +59,18 @@ public class AuthenticatorTestCase {
private Server server;
private String host = null;
private int port = -1;
+ private boolean useTomcat = false;
+ private Tomcat tomcat = null;
Context context;
private static Properties authenticatorConfig;
+ public AuthenticatorTestCase() {}
+
+ public AuthenticatorTestCase(boolean useTomcat) {
+ this.useTomcat = useTomcat;
+ }
+
protected static void setAuthenticationHandlerConfig(Properties config) {
authenticatorConfig = config;
}
@@ -80,7 +106,19 @@ public class AuthenticatorTestCase {
}
}
+ protected int getLocalPort() throws Exception {
+ ServerSocket ss = new ServerSocket(0);
+ int ret = ss.getLocalPort();
+ ss.close();
+ return ret;
+ }
+
protected void start() throws Exception {
+ if (useTomcat) startTomcat();
+ else startJetty();
+ }
+
+ protected void startJetty() throws Exception {
server = new Server(0);
context = new Context();
context.setContextPath("/foo");
@@ -88,16 +126,42 @@ public class AuthenticatorTestCase {
context.addFilter(new FilterHolder(TestFilter.class), "/*", 0);
context.addServlet(new ServletHolder(TestServlet.class), "/bar");
host = "localhost";
- ServerSocket ss = new ServerSocket(0);
- port = ss.getLocalPort();
- ss.close();
+ port = getLocalPort();
server.getConnectors()[0].setHost(host);
server.getConnectors()[0].setPort(port);
server.start();
System.out.println("Running embedded servlet container at: http://" + host + ":" + port);
}
+ protected void startTomcat() throws Exception {
+ tomcat = new Tomcat();
+ File base = new File(System.getProperty("java.io.tmpdir"));
+ org.apache.catalina.Context ctx =
+ tomcat.addContext("/foo",base.getAbsolutePath());
+ FilterDef fd = new FilterDef();
+ fd.setFilterClass(TestFilter.class.getName());
+ fd.setFilterName("TestFilter");
+ FilterMap fm = new FilterMap();
+ fm.setFilterName("TestFilter");
+ fm.addURLPattern("/*");
+ fm.addServletName("/bar");
+ ctx.addFilterDef(fd);
+ ctx.addFilterMap(fm);
+ tomcat.addServlet(ctx, "/bar", TestServlet.class.getName());
+ ctx.addServletMapping("/bar", "/bar");
+ host = "localhost";
+ port = getLocalPort();
+ tomcat.setHostname(host);
+ tomcat.setPort(port);
+ tomcat.start();
+ }
+
protected void stop() throws Exception {
+ if (useTomcat) stopTomcat();
+ else stopJetty();
+ }
+
+ protected void stopJetty() throws Exception {
try {
server.stop();
} catch (Exception e) {
@@ -109,6 +173,18 @@ public class AuthenticatorTestCase {
}
}
+ protected void stopTomcat() throws Exception {
+ try {
+ tomcat.stop();
+ } catch (Exception e) {
+ }
+
+ try {
+ tomcat.destroy();
+ } catch (Exception e) {
+ }
+ }
+
protected String getBaseURL() {
return "http://" + host + ":" + port + "/foo/bar";
}
@@ -165,4 +241,57 @@ public class AuthenticatorTestCase {
}
}
+ private SystemDefaultHttpClient getHttpClient() {
+ final SystemDefaultHttpClient httpClient = new SystemDefaultHttpClient();
+ httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory(true));
+ Credentials use_jaas_creds = new Credentials() {
+ public String getPassword() {
+ return null;
+ }
+
+ public Principal getUserPrincipal() {
+ return null;
+ }
+ };
+
+ httpClient.getCredentialsProvider().setCredentials(
+ AuthScope.ANY, use_jaas_creds);
+ return httpClient;
+ }
+
+ private void doHttpClientRequest(HttpClient httpClient, HttpUriRequest request) throws Exception {
+ HttpResponse response = null;
+ try {
+ response = httpClient.execute(request);
+ final int httpStatus = response.getStatusLine().getStatusCode();
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, httpStatus);
+ } finally {
+ if (response != null) EntityUtils.consumeQuietly(response.getEntity());
+ }
+ }
+
+ protected void _testAuthenticationHttpClient(Authenticator authenticator, boolean doPost) throws Exception {
+ start();
+ try {
+ SystemDefaultHttpClient httpClient = getHttpClient();
+ doHttpClientRequest(httpClient, new HttpGet(getBaseURL()));
+
+ // Always do a GET before POST to trigger the SPNego negotiation
+ if (doPost) {
+ HttpPost post = new HttpPost(getBaseURL());
+ byte [] postBytes = POST.getBytes();
+ ByteArrayInputStream bis = new ByteArrayInputStream(postBytes);
+ InputStreamEntity entity = new InputStreamEntity(bis, postBytes.length);
+
+ // Important that the entity is not repeatable -- this means if
+ // we have to renegotiate (e.g. b/c the cookie wasn't handled properly)
+ // the test will fail.
+ Assert.assertFalse(entity.isRepeatable());
+ post.setEntity(entity);
+ doHttpClientRequest(httpClient, post);
+ }
+ } finally {
+ stop();
+ }
+ }
}
diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/TestKerberosAuthenticator.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/TestKerberosAuthenticator.java
index 53d23c467a4..6c49d15f09a 100644
--- a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/TestKerberosAuthenticator.java
+++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/TestKerberosAuthenticator.java
@@ -20,16 +20,36 @@ import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHand
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runner.RunWith;
import org.junit.Test;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.Callable;
+@RunWith(Parameterized.class)
public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
+ private boolean useTomcat = false;
+
+ public TestKerberosAuthenticator(boolean useTomcat) {
+ this.useTomcat = useTomcat;
+ }
+
+ @Parameterized.Parameters
+ public static Collection booleans() {
+ return Arrays.asList(new Object[][] {
+ { false },
+ { true }
+ });
+ }
+
@Before
public void setup() throws Exception {
// create keytab
@@ -53,7 +73,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
@Test(timeout=60000)
public void testFallbacktoPseudoAuthenticator() throws Exception {
- AuthenticatorTestCase auth = new AuthenticatorTestCase();
+ AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
Properties props = new Properties();
props.setProperty(AuthenticationFilter.AUTH_TYPE, "simple");
props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "false");
@@ -63,7 +83,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
@Test(timeout=60000)
public void testFallbacktoPseudoAuthenticatorAnonymous() throws Exception {
- AuthenticatorTestCase auth = new AuthenticatorTestCase();
+ AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
Properties props = new Properties();
props.setProperty(AuthenticationFilter.AUTH_TYPE, "simple");
props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "true");
@@ -73,7 +93,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
@Test(timeout=60000)
public void testNotAuthenticated() throws Exception {
- AuthenticatorTestCase auth = new AuthenticatorTestCase();
+ AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
AuthenticatorTestCase.setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration());
auth.start();
try {
@@ -89,7 +109,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
@Test(timeout=60000)
public void testAuthentication() throws Exception {
- final AuthenticatorTestCase auth = new AuthenticatorTestCase();
+ final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
AuthenticatorTestCase.setAuthenticationHandlerConfig(
getAuthenticationHandlerConfiguration());
KerberosTestUtils.doAsClient(new Callable() {
@@ -103,7 +123,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
@Test(timeout=60000)
public void testAuthenticationPost() throws Exception {
- final AuthenticatorTestCase auth = new AuthenticatorTestCase();
+ final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
AuthenticatorTestCase.setAuthenticationHandlerConfig(
getAuthenticationHandlerConfiguration());
KerberosTestUtils.doAsClient(new Callable() {
@@ -114,4 +134,32 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
}
});
}
+
+ @Test(timeout=60000)
+ public void testAuthenticationHttpClient() throws Exception {
+ final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
+ AuthenticatorTestCase.setAuthenticationHandlerConfig(
+ getAuthenticationHandlerConfiguration());
+ KerberosTestUtils.doAsClient(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ auth._testAuthenticationHttpClient(new KerberosAuthenticator(), false);
+ return null;
+ }
+ });
+ }
+
+ @Test(timeout=60000)
+ public void testAuthenticationHttpClientPost() throws Exception {
+ final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
+ AuthenticatorTestCase.setAuthenticationHandlerConfig(
+ getAuthenticationHandlerConfiguration());
+ KerberosTestUtils.doAsClient(new Callable() {
+ @Override
+ public Void call() throws Exception {
+ auth._testAuthenticationHttpClient(new KerberosAuthenticator(), true);
+ return null;
+ }
+ });
+ }
}
diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt
index 717bd249784..637636479f2 100644
--- a/hadoop-common-project/hadoop-common/CHANGES.txt
+++ b/hadoop-common-project/hadoop-common/CHANGES.txt
@@ -710,6 +710,9 @@ Release 2.6.0 - UNRELEASED
loaded. (umamahesh)
--
+ HADOOP-10911. hadoop.auth cookie after HADOOP-10710 still not proper
+ according to RFC2109. (gchanan via tucu)
+
Release 2.5.1 - UNRELEASED
INCOMPATIBLE CHANGES
diff --git a/hadoop-project/pom.xml b/hadoop-project/pom.xml
index beaeec63a77..e9adc315922 100644
--- a/hadoop-project/pom.xml
+++ b/hadoop-project/pom.xml
@@ -398,6 +398,16 @@
jetty-util
6.1.26
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ 7.0.55
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-logging-juli
+ 7.0.55
+
javax.servlet.jsp
jsp-api