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 dc7f0adeb3..b4e0270d31 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 @@ -425,14 +425,20 @@ public Principal getUserPrincipal() { * cookie. It has no effect if its value < 0. * * XXX the following code duplicate some logic in Jetty / Servlet API, - * because of the fact that Hadoop is stuck at servlet 3.0 and jetty 6 + * because of the fact that Hadoop is stuck at servlet 2.5 and jetty 6 * right now. */ public static void createAuthCookie(HttpServletResponse resp, String token, String domain, String path, long expires, boolean isSecure) { - StringBuilder sb = new StringBuilder(AuthenticatedURL.AUTH_COOKIE).append - ("=").append(token); + StringBuilder sb = new StringBuilder(AuthenticatedURL.AUTH_COOKIE) + .append("="); + if (token != null && token.length() > 0) { + sb.append("\"") + .append(token) + .append("\""); + } + sb.append("; Version=1"); if (path != null) { sb.append("; Path=").append(path); diff --git a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java index 989025fbf8..2cc36587c8 100644 --- a/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java +++ b/hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/server/TestAuthenticationFilter.java @@ -531,21 +531,17 @@ public Object answer(InvocationOnMock invocation) throws Throwable { private static void parseCookieMap(String cookieHeader, HashMap cookieMap) { - for (String pair : cookieHeader.split(";")) { - String p = pair.trim(); - int idx = p.indexOf('='); - final String k, v; - if (idx == -1) { - k = p; - v = null; - } else if (idx == p.length()) { - k = p.substring(0, idx - 1); - v = null; - } else { - k = p.substring(0, idx); - v = p.substring(idx + 1); + List cookies = HttpCookie.parse(cookieHeader); + for (HttpCookie cookie : cookies) { + if (AuthenticatedURL.AUTH_COOKIE.equals(cookie.getName())) { + cookieMap.put(cookie.getName(), cookie.getValue()); + if (cookie.getPath() != null) { + cookieMap.put("Path", cookie.getPath()); + } + if (cookie.getDomain() != null) { + cookieMap.put("Domain", cookie.getDomain()); + } } - cookieMap.put(k, v); } } diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 4a3f548ab5..d2d74a3e4a 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -665,6 +665,9 @@ Release 2.5.0 - UNRELEASED HADOOP-10715. Remove public GraphiteSink#setWriter (Babak Behzad via raviprak) + HADOOP-10710. hadoop.auth cookie is not properly constructed according to + RFC2109. (Juan Yu via tucu) + Release 2.4.1 - 2014-06-23 INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpCookieFlag.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpCookieFlag.java index d7104aaf75..75a9480482 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpCookieFlag.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpCookieFlag.java @@ -36,6 +36,8 @@ import java.net.URI; import java.net.URL; import java.security.GeneralSecurityException; +import java.net.HttpCookie; +import java.util.List; public class TestHttpCookieFlag { private static final String BASEDIR = System.getProperty("test.build.dir", @@ -116,8 +118,12 @@ public void testHttpCookie() throws IOException { .getConnectorAddress(0))); HttpURLConnection conn = (HttpURLConnection) new URL(base, "/echo").openConnection(); - Assert.assertEquals(AuthenticatedURL.AUTH_COOKIE + "=token; " + - "HttpOnly", conn.getHeaderField("Set-Cookie")); + + String header = conn.getHeaderField("Set-Cookie"); + List cookies = HttpCookie.parse(header); + Assert.assertTrue(!cookies.isEmpty()); + Assert.assertTrue(header.contains("; HttpOnly")); + Assert.assertTrue("token".equals(cookies.get(0).getValue())); } @Test @@ -127,8 +133,13 @@ public void testHttpsCookie() throws IOException, GeneralSecurityException { HttpsURLConnection conn = (HttpsURLConnection) new URL(base, "/echo").openConnection(); conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory()); - Assert.assertEquals(AuthenticatedURL.AUTH_COOKIE + "=token; " + - "Secure; HttpOnly", conn.getHeaderField("Set-Cookie")); + + String header = conn.getHeaderField("Set-Cookie"); + List cookies = HttpCookie.parse(header); + Assert.assertTrue(!cookies.isEmpty()); + Assert.assertTrue(header.contains("; HttpOnly")); + Assert.assertTrue(cookies.get(0).getSecure()); + Assert.assertTrue("token".equals(cookies.get(0).getValue())); } @AfterClass