You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by at...@apache.org on 2011/08/20 00:31:09 UTC

svn commit: r1159804 [3/3] - in /hadoop/common/trunk: ./ hadoop-alfredo/ hadoop-alfredo/src/ hadoop-alfredo/src/examples/ hadoop-alfredo/src/examples/src/ hadoop-alfredo/src/examples/src/main/ hadoop-alfredo/src/examples/src/main/java/ hadoop-alfredo/s...

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/client/TestPseudoAuthenticator.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/client/TestPseudoAuthenticator.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/client/TestPseudoAuthenticator.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/client/TestPseudoAuthenticator.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,83 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.client;
+
+import org.apache.hadoop.alfredo.server.AuthenticationFilter;
+import org.apache.hadoop.alfredo.server.PseudoAuthenticationHandler;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Properties;
+
+public class TestPseudoAuthenticator extends AuthenticatorTestCase {
+
+  private Properties getAuthenticationHandlerConfiguration(boolean anonymousAllowed) {
+    Properties props = new Properties();
+    props.setProperty(AuthenticationFilter.AUTH_TYPE, "simple");
+    props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, Boolean.toString(anonymousAllowed));
+    return props;
+  }
+
+  public void testGetUserName() throws Exception {
+    PseudoAuthenticator authenticator = new PseudoAuthenticator();
+    assertEquals(System.getProperty("user.name"), authenticator.getUserName());
+  }
+
+  public void testAnonymousAllowed() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(true));
+    start();
+    try {
+      URL url = new URL(getBaseURL());
+      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+      conn.connect();
+      assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
+    } finally {
+      stop();
+    }
+  }
+
+  public void testAnonymousDisallowed() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(false));
+    start();
+    try {
+      URL url = new URL(getBaseURL());
+      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+      conn.connect();
+      assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, conn.getResponseCode());
+    } finally {
+      stop();
+    }
+  }
+
+  public void testAuthenticationAnonymousAllowed() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(true));
+    _testAuthentication(new PseudoAuthenticator(), false);
+  }
+
+  public void testAuthenticationAnonymousDisallowed() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(false));
+    _testAuthentication(new PseudoAuthenticator(), false);
+  }
+
+  public void testAuthenticationAnonymousAllowedWithPost() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(true));
+    _testAuthentication(new PseudoAuthenticator(), true);
+  }
+
+  public void testAuthenticationAnonymousDisallowedWithPost() throws Exception {
+    setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration(false));
+    _testAuthentication(new PseudoAuthenticator(), true);
+  }
+
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationFilter.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationFilter.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationFilter.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationFilter.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,611 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.server;
+
+import org.apache.hadoop.alfredo.client.AuthenticatedURL;
+import org.apache.hadoop.alfredo.client.AuthenticationException;
+import org.apache.hadoop.alfredo.util.Signer;
+import junit.framework.TestCase;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.Vector;
+
+public class TestAuthenticationFilter extends TestCase {
+
+  public void testGetConfiguration() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    FilterConfig config = Mockito.mock(FilterConfig.class);
+    Mockito.when(config.getInitParameter(AuthenticationFilter.CONFIG_PREFIX)).thenReturn("");
+    Mockito.when(config.getInitParameter("a")).thenReturn("A");
+    Mockito.when(config.getInitParameterNames()).thenReturn(new Vector(Arrays.asList("a")).elements());
+    Properties props = filter.getConfiguration("", config);
+    assertEquals("A", props.getProperty("a"));
+
+    config = Mockito.mock(FilterConfig.class);
+    Mockito.when(config.getInitParameter(AuthenticationFilter.CONFIG_PREFIX)).thenReturn("foo");
+    Mockito.when(config.getInitParameter("foo.a")).thenReturn("A");
+    Mockito.when(config.getInitParameterNames()).thenReturn(new Vector(Arrays.asList("foo.a")).elements());
+    props = filter.getConfiguration("foo.", config);
+    assertEquals("A", props.getProperty("a"));
+  }
+
+  public void testInitEmpty() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameterNames()).thenReturn(new Vector().elements());
+      filter.init(config);
+      fail();
+    } catch (ServletException ex) {
+      // Expected
+    } catch (Exception ex) {
+      fail();
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public static class DummyAuthenticationHandler implements AuthenticationHandler {
+    public static boolean init;
+    public static boolean destroy;
+
+    public static final String TYPE = "dummy";
+
+    public static void reset() {
+      init = false;
+      destroy = false;
+    }
+
+    @Override
+    public void init(Properties config) throws ServletException {
+      init = true;
+    }
+
+    @Override
+    public void destroy() {
+      destroy = true;
+    }
+
+    @Override
+    public String getType() {
+      return TYPE;
+    }
+
+    @Override
+    public AuthenticationToken authenticate(HttpServletRequest request, HttpServletResponse response)
+      throws IOException, AuthenticationException {
+      AuthenticationToken token = null;
+      String param = request.getParameter("authenticated");
+      if (param != null && param.equals("true")) {
+        token = new AuthenticationToken("u", "p", "t");
+        token.setExpires(System.currentTimeMillis() + 1000);
+      } else {
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+      }
+      return token;
+    }
+  }
+
+  public void testInit() throws Exception {
+
+    // minimal configuration & simple auth handler (Pseudo)
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn("simple");
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TOKEN_VALIDITY)).thenReturn("1000");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.AUTH_TOKEN_VALIDITY)).elements());
+      filter.init(config);
+      assertEquals(PseudoAuthenticationHandler.class, filter.getAuthenticationHandler().getClass());
+      assertTrue(filter.isRandomSecret());
+      assertNull(filter.getCookieDomain());
+      assertNull(filter.getCookiePath());
+      assertEquals(1000, filter.getValidity());
+    } finally {
+      filter.destroy();
+    }
+
+    // custom secret
+    filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn("simple");
+      Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.SIGNATURE_SECRET)).elements());
+      filter.init(config);
+      assertFalse(filter.isRandomSecret());
+    } finally {
+      filter.destroy();
+    }
+
+    // custom cookie domain and cookie path
+    filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn("simple");
+      Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_DOMAIN)).thenReturn(".foo.com");
+      Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_PATH)).thenReturn("/bar");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.COOKIE_DOMAIN,
+                                 AuthenticationFilter.COOKIE_PATH)).elements());
+      filter.init(config);
+      assertEquals(".foo.com", filter.getCookieDomain());
+      assertEquals("/bar", filter.getCookiePath());
+    } finally {
+      filter.destroy();
+    }
+
+
+    // authentication handler lifecycle, and custom impl
+    DummyAuthenticationHandler.reset();
+    filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+      assertTrue(DummyAuthenticationHandler.init);
+    } finally {
+      filter.destroy();
+      assertTrue(DummyAuthenticationHandler.destroy);
+    }
+
+    // kerberos auth handler
+    filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn("kerberos");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+    } catch (ServletException ex) {
+      // Expected
+    } finally {
+      assertEquals(KerberosAuthenticationHandler.class, filter.getAuthenticationHandler().getClass());
+      filter.destroy();
+    }
+  }
+
+  public void testGetRequestURL() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+      Mockito.when(request.getQueryString()).thenReturn("a=A&b=B");
+
+      assertEquals("http://foo:8080/bar?a=A&b=B", filter.getRequestURL(request));
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testGetToken() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.SIGNATURE_SECRET)).elements());
+      filter.init(config);
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", DummyAuthenticationHandler.TYPE);
+      token.setExpires(System.currentTimeMillis() + 1000);
+      Signer signer = new Signer("secret".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      AuthenticationToken newToken = filter.getToken(request);
+
+      assertEquals(token.toString(), newToken.toString());
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testGetTokenExpired() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.SIGNATURE_SECRET)).elements());
+      filter.init(config);
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", "invalidtype");
+      token.setExpires(System.currentTimeMillis() - 1000);
+      Signer signer = new Signer("secret".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      try {
+        filter.getToken(request);
+        fail();
+      } catch (AuthenticationException ex) {
+        // Expected
+      } catch (Exception ex) {
+        fail();
+      }
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testGetTokenInvalidType() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.SIGNATURE_SECRET)).elements());
+      filter.init(config);
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", "invalidtype");
+      token.setExpires(System.currentTimeMillis() + 1000);
+      Signer signer = new Signer("secret".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      try {
+        filter.getToken(request);
+        fail();
+      } catch (AuthenticationException ex) {
+        // Expected
+      } catch (Exception ex) {
+        fail();
+      }
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testDoFilterNotAuthenticated() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      FilterChain chain = Mockito.mock(FilterChain.class);
+
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            fail();
+            return null;
+          }
+        }
+      ).when(chain).doFilter(Mockito.<ServletRequest>anyObject(), Mockito.<ServletResponse>anyObject());
+
+      filter.doFilter(request, response, chain);
+
+      Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  private void _testDoFilterAuthentication(boolean withDomainPath) throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TOKEN_VALIDITY)).thenReturn("1000");
+      Mockito.when(config.getInitParameter(AuthenticationFilter.SIGNATURE_SECRET)).thenReturn("secret");
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                 AuthenticationFilter.AUTH_TOKEN_VALIDITY,
+                                 AuthenticationFilter.SIGNATURE_SECRET)).elements());
+
+      if (withDomainPath) {
+        Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_DOMAIN)).thenReturn(".foo.com");
+        Mockito.when(config.getInitParameter(AuthenticationFilter.COOKIE_PATH)).thenReturn("/bar");
+        Mockito.when(config.getInitParameterNames()).thenReturn(
+          new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE,
+                                   AuthenticationFilter.AUTH_TOKEN_VALIDITY,
+                                   AuthenticationFilter.SIGNATURE_SECRET,
+                                   AuthenticationFilter.COOKIE_DOMAIN,
+                                   AuthenticationFilter.COOKIE_PATH)).elements());
+      }
+
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getParameter("authenticated")).thenReturn("true");
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+      Mockito.when(request.getQueryString()).thenReturn("authenticated=true");
+
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      FilterChain chain = Mockito.mock(FilterChain.class);
+
+      final boolean[] calledDoFilter = new boolean[1];
+
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            calledDoFilter[0] = true;
+            return null;
+          }
+        }
+      ).when(chain).doFilter(Mockito.<ServletRequest>anyObject(), Mockito.<ServletResponse>anyObject());
+
+      final Cookie[] setCookie = new Cookie[1];
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            Object[] args = invocation.getArguments();
+            setCookie[0] = (Cookie) args[0];
+            return null;
+          }
+        }
+      ).when(response).addCookie(Mockito.<Cookie>anyObject());
+
+      filter.doFilter(request, response, chain);
+
+      assertNotNull(setCookie[0]);
+      assertEquals(AuthenticatedURL.AUTH_COOKIE, setCookie[0].getName());
+      assertTrue(setCookie[0].getValue().contains("u="));
+      assertTrue(setCookie[0].getValue().contains("p="));
+      assertTrue(setCookie[0].getValue().contains("t="));
+      assertTrue(setCookie[0].getValue().contains("e="));
+      assertTrue(setCookie[0].getValue().contains("s="));
+      assertTrue(calledDoFilter[0]);
+
+      Signer signer = new Signer("secret".getBytes());
+      String value = signer.verifyAndExtract(setCookie[0].getValue());
+      AuthenticationToken token = AuthenticationToken.parse(value);
+      assertEquals(System.currentTimeMillis() + 1000 * 1000, token.getExpires(), 100);
+
+      if (withDomainPath) {
+        assertEquals(".foo.com", setCookie[0].getDomain());
+        assertEquals("/bar", setCookie[0].getPath());
+      } else {
+        assertNull(setCookie[0].getDomain());
+        assertNull(setCookie[0].getPath());
+      }
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testDoFilterAuthentication() throws Exception {
+    _testDoFilterAuthentication(false);
+  }
+
+  public void testDoFilterAuthenticationWithDomainPath() throws Exception {
+    _testDoFilterAuthentication(true);
+  }
+
+  public void testDoFilterAuthenticated() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", "t");
+      token.setExpires(System.currentTimeMillis() + 1000);
+      Signer signer = new Signer("alfredo".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      FilterChain chain = Mockito.mock(FilterChain.class);
+
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            Object[] args = invocation.getArguments();
+            HttpServletRequest request = (HttpServletRequest) args[0];
+            assertEquals("u", request.getRemoteUser());
+            assertEquals("p", request.getUserPrincipal().getName());
+            return null;
+          }
+        }
+      ).when(chain).doFilter(Mockito.<ServletRequest>anyObject(), Mockito.<ServletResponse>anyObject());
+
+      filter.doFilter(request, response, chain);
+
+    } finally {
+      filter.destroy();
+    }
+  }
+
+  public void testDoFilterAuthenticatedExpired() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", DummyAuthenticationHandler.TYPE);
+      token.setExpires(System.currentTimeMillis() - 1000);
+      Signer signer = new Signer("alfredo".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      FilterChain chain = Mockito.mock(FilterChain.class);
+
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            fail();
+            return null;
+          }
+        }
+      ).when(chain).doFilter(Mockito.<ServletRequest>anyObject(), Mockito.<ServletResponse>anyObject());
+
+      final Cookie[] setCookie = new Cookie[1];
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            Object[] args = invocation.getArguments();
+            setCookie[0] = (Cookie) args[0];
+            return null;
+          }
+        }
+      ).when(response).addCookie(Mockito.<Cookie>anyObject());
+
+      filter.doFilter(request, response, chain);
+
+      Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), Mockito.anyString());
+
+      assertNotNull(setCookie[0]);
+      assertEquals(AuthenticatedURL.AUTH_COOKIE, setCookie[0].getName());
+      assertEquals("", setCookie[0].getValue());
+    } finally {
+      filter.destroy();
+    }
+  }
+
+
+  public void testDoFilterAuthenticatedInvalidType() throws Exception {
+    AuthenticationFilter filter = new AuthenticationFilter();
+    try {
+      FilterConfig config = Mockito.mock(FilterConfig.class);
+      Mockito.when(config.getInitParameter(AuthenticationFilter.AUTH_TYPE)).thenReturn(
+        DummyAuthenticationHandler.class.getName());
+      Mockito.when(config.getInitParameterNames()).thenReturn(
+        new Vector(Arrays.asList(AuthenticationFilter.AUTH_TYPE)).elements());
+      filter.init(config);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://foo:8080/bar"));
+
+      AuthenticationToken token = new AuthenticationToken("u", "p", "invalidtype");
+      token.setExpires(System.currentTimeMillis() + 1000);
+      Signer signer = new Signer("alfredo".getBytes());
+      String tokenSigned = signer.sign(token.toString());
+
+      Cookie cookie = new Cookie(AuthenticatedURL.AUTH_COOKIE, tokenSigned);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[]{cookie});
+
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      FilterChain chain = Mockito.mock(FilterChain.class);
+
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            fail();
+            return null;
+          }
+        }
+      ).when(chain).doFilter(Mockito.<ServletRequest>anyObject(), Mockito.<ServletResponse>anyObject());
+
+      final Cookie[] setCookie = new Cookie[1];
+      Mockito.doAnswer(
+        new Answer() {
+          @Override
+          public Object answer(InvocationOnMock invocation) throws Throwable {
+            Object[] args = invocation.getArguments();
+            setCookie[0] = (Cookie) args[0];
+            return null;
+          }
+        }
+      ).when(response).addCookie(Mockito.<Cookie>anyObject());
+
+      filter.doFilter(request, response, chain);
+
+      Mockito.verify(response).sendError(Mockito.eq(HttpServletResponse.SC_UNAUTHORIZED), Mockito.anyString());
+
+      assertNotNull(setCookie[0]);
+      assertEquals(AuthenticatedURL.AUTH_COOKIE, setCookie[0].getName());
+      assertEquals("", setCookie[0].getValue());
+    } finally {
+      filter.destroy();
+    }
+  }
+
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationToken.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationToken.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationToken.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestAuthenticationToken.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,124 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.server;
+
+import org.apache.hadoop.alfredo.client.AuthenticationException;
+import junit.framework.TestCase;
+
+public class TestAuthenticationToken extends TestCase {
+
+  public void testAnonymous() {
+    assertNotNull(AuthenticationToken.ANONYMOUS);
+    assertEquals(null, AuthenticationToken.ANONYMOUS.getUserName());
+    assertEquals(null, AuthenticationToken.ANONYMOUS.getName());
+    assertEquals(null, AuthenticationToken.ANONYMOUS.getType());
+    assertEquals(-1, AuthenticationToken.ANONYMOUS.getExpires());
+    assertFalse(AuthenticationToken.ANONYMOUS.isExpired());
+  }
+
+  public void testConstructor() throws Exception {
+    try {
+      new AuthenticationToken(null, "p", "t");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      new AuthenticationToken("", "p", "t");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      new AuthenticationToken("u", null, "t");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      new AuthenticationToken("u", "", "t");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      new AuthenticationToken("u", "p", null);
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      new AuthenticationToken("u", "p", "");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    new AuthenticationToken("u", "p", "t");
+  }
+
+  public void testGetters() throws Exception {
+    long expires = System.currentTimeMillis() + 50;
+    AuthenticationToken token = new AuthenticationToken("u", "p", "t");
+    token.setExpires(expires);
+    assertEquals("u", token.getUserName());
+    assertEquals("p", token.getName());
+    assertEquals("t", token.getType());
+    assertEquals(expires, token.getExpires());
+    assertFalse(token.isExpired());
+    Thread.sleep(51);
+    assertTrue(token.isExpired());
+  }
+
+  public void testToStringAndParse() throws Exception {
+    long expires = System.currentTimeMillis() + 50;
+    AuthenticationToken token = new AuthenticationToken("u", "p", "t");
+    token.setExpires(expires);
+    String str = token.toString();
+    token = AuthenticationToken.parse(str);
+    assertEquals("p", token.getName());
+    assertEquals("t", token.getType());
+    assertEquals(expires, token.getExpires());
+    assertFalse(token.isExpired());
+    Thread.sleep(51);
+    assertTrue(token.isExpired());
+  }
+
+  public void testParseInvalid() throws Exception {
+    long expires = System.currentTimeMillis() + 50;
+    AuthenticationToken token = new AuthenticationToken("u", "p", "t");
+    token.setExpires(expires);
+    String str = token.toString();
+    str = str.substring(0, str.indexOf("e="));
+    try {
+      AuthenticationToken.parse(str);
+      fail();
+    } catch (AuthenticationException ex) {
+      // Expected
+    } catch (Exception ex) {
+      fail();
+    }
+  }
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestKerberosAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestKerberosAuthenticationHandler.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestKerberosAuthenticationHandler.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestKerberosAuthenticationHandler.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,178 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.server;
+
+import org.apache.hadoop.alfredo.KerberosTestUtils;
+import org.apache.hadoop.alfredo.client.AuthenticationException;
+import org.apache.hadoop.alfredo.client.KerberosAuthenticator;
+import junit.framework.TestCase;
+import org.apache.commons.codec.binary.Base64;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.mockito.Mockito;
+import sun.security.jgss.GSSUtil;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+
+public class TestKerberosAuthenticationHandler extends TestCase {
+
+  private KerberosAuthenticationHandler handler;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    handler = new KerberosAuthenticationHandler();
+    Properties props = new Properties();
+    props.setProperty(KerberosAuthenticationHandler.PRINCIPAL, KerberosTestUtils.getServerPrincipal());
+    props.setProperty(KerberosAuthenticationHandler.KEYTAB, KerberosTestUtils.getKeytabFile());
+    props.setProperty(KerberosAuthenticationHandler.NAME_RULES,
+                      "RULE:[1:$1@$0](.*@" + KerberosTestUtils.getRealm()+")s/@.*//\n");
+    try {
+      handler.init(props);
+    } catch (Exception ex) {
+      handler = null;
+      throw ex;
+    }
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    if (handler != null) {
+      handler.destroy();
+      handler = null;
+    }
+    super.tearDown();
+  }
+
+  public void testInit() throws Exception {
+    assertEquals(KerberosTestUtils.getServerPrincipal(), handler.getPrincipal());
+    assertEquals(KerberosTestUtils.getKeytabFile(), handler.getKeytab());
+  }
+
+  public void testType() throws Exception {
+    KerberosAuthenticationHandler handler = new KerberosAuthenticationHandler();
+    assertEquals(KerberosAuthenticationHandler.TYPE, handler.getType());
+  }
+
+  public void testRequestWithoutAuthorization() throws Exception {
+    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+    assertNull(handler.authenticate(request, response));
+    Mockito.verify(response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
+    Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+  }
+
+  public void testRequestWithInvalidAuthorization() throws Exception {
+    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION)).thenReturn("invalid");
+    assertNull(handler.authenticate(request, response));
+    Mockito.verify(response).setHeader(KerberosAuthenticator.WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
+    Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+  }
+
+  public void testRequestWithIncompleteAuthorization() throws Exception {
+    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION))
+      .thenReturn(KerberosAuthenticator.NEGOTIATE);
+    try {
+      handler.authenticate(request, response);
+      fail();
+    } catch (AuthenticationException ex) {
+      // Expected
+    } catch (Exception ex) {
+      fail();
+    }
+  }
+
+
+  public void testRequestWithAuthorization() throws Exception {
+    String token = KerberosTestUtils.doAsClient(new Callable<String>() {
+      @Override
+      public String call() throws Exception {
+        GSSManager gssManager = GSSManager.getInstance();
+        GSSContext gssContext = null;
+        try {
+          String servicePrincipal = KerberosTestUtils.getServerPrincipal();
+          GSSName serviceName = gssManager.createName(servicePrincipal, GSSUtil.NT_GSS_KRB5_PRINCIPAL);
+          gssContext = gssManager.createContext(serviceName, GSSUtil.GSS_KRB5_MECH_OID, null,
+                                                GSSContext.DEFAULT_LIFETIME);
+          gssContext.requestCredDeleg(true);
+          gssContext.requestMutualAuth(true);
+
+          byte[] inToken = new byte[0];
+          byte[] outToken = gssContext.initSecContext(inToken, 0, inToken.length);
+          Base64 base64 = new Base64(0);
+          return base64.encodeToString(outToken);
+
+        } finally {
+          if (gssContext != null) {
+            gssContext.dispose();
+          }
+        }
+      }
+    });
+
+    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION))
+      .thenReturn(KerberosAuthenticator.NEGOTIATE + " " + token);
+
+    AuthenticationToken authToken = handler.authenticate(request, response);
+
+    if (authToken != null) {
+      Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE),
+                                         Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
+      Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
+
+      assertEquals(KerberosTestUtils.getClientPrincipal(), authToken.getName());
+      assertTrue(KerberosTestUtils.getClientPrincipal().startsWith(authToken.getUserName()));
+      assertEquals(KerberosAuthenticationHandler.TYPE, authToken.getType());
+    } else {
+      Mockito.verify(response).setHeader(Mockito.eq(KerberosAuthenticator.WWW_AUTHENTICATE),
+                                         Mockito.matches(KerberosAuthenticator.NEGOTIATE + " .*"));
+      Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+    }
+  }
+
+  public void testRequestWithInvalidKerberosAuthorization() throws Exception {
+
+    String token = new Base64(0).encodeToString(new byte[]{0, 1, 2});
+
+    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+    Mockito.when(request.getHeader(KerberosAuthenticator.AUTHORIZATION)).thenReturn(
+      KerberosAuthenticator.NEGOTIATE + token);
+
+    try {
+      handler.authenticate(request, response);
+      fail();
+    } catch (AuthenticationException ex) {
+      // Expected
+    } catch (Exception ex) {
+      fail();
+    }
+  }
+
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestPseudoAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestPseudoAuthenticationHandler.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestPseudoAuthenticationHandler.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/server/TestPseudoAuthenticationHandler.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,113 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.server;
+
+import org.apache.hadoop.alfredo.client.AuthenticationException;
+import junit.framework.TestCase;
+import org.apache.hadoop.alfredo.client.PseudoAuthenticator;
+import org.mockito.Mockito;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Properties;
+
+public class TestPseudoAuthenticationHandler extends TestCase {
+
+  public void testInit() throws Exception {
+    PseudoAuthenticationHandler handler = new PseudoAuthenticationHandler();
+    try {
+      Properties props = new Properties();
+      props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "false");
+      handler.init(props);
+      assertEquals(false, handler.getAcceptAnonymous());
+    } finally {
+      handler.destroy();
+    }
+  }
+
+  public void testType() throws Exception {
+    PseudoAuthenticationHandler handler = new PseudoAuthenticationHandler();
+    assertEquals(PseudoAuthenticationHandler.TYPE, handler.getType());
+  }
+
+  public void testAnonymousOn() throws Exception {
+    PseudoAuthenticationHandler handler = new PseudoAuthenticationHandler();
+    try {
+      Properties props = new Properties();
+      props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "true");
+      handler.init(props);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      AuthenticationToken token = handler.authenticate(request, response);
+
+      assertEquals(AuthenticationToken.ANONYMOUS, token);
+    } finally {
+      handler.destroy();
+    }
+  }
+
+  public void testAnonymousOff() throws Exception {
+    PseudoAuthenticationHandler handler = new PseudoAuthenticationHandler();
+    try {
+      Properties props = new Properties();
+      props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "false");
+      handler.init(props);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+
+      handler.authenticate(request, response);
+      fail();
+    } catch (AuthenticationException ex) {
+      // Expected
+    } catch (Exception ex) {
+      fail();
+    } finally {
+      handler.destroy();
+    }
+  }
+
+  private void _testUserName(boolean anonymous) throws Exception {
+    PseudoAuthenticationHandler handler = new PseudoAuthenticationHandler();
+    try {
+      Properties props = new Properties();
+      props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, Boolean.toString(anonymous));
+      handler.init(props);
+
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+      Mockito.when(request.getParameter(PseudoAuthenticator.USER_NAME)).thenReturn("user");
+
+      AuthenticationToken token = handler.authenticate(request, response);
+
+      assertNotNull(token);
+      assertEquals("user", token.getUserName());
+      assertEquals("user", token.getName());
+      assertEquals(PseudoAuthenticationHandler.TYPE, token.getType());
+    } finally {
+      handler.destroy();
+    }
+  }
+
+  public void testUserNameAnonymousOff() throws Exception {
+    _testUserName(false);
+  }
+
+  public void testUserNameAnonymousOn() throws Exception {
+    _testUserName(true);
+  }
+
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestKerberosName.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestKerberosName.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestKerberosName.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestKerberosName.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,88 @@
+package org.apache.hadoop.alfredo.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.hadoop.alfredo.KerberosTestUtils;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class TestKerberosName {
+
+  @Before
+  public void setUp() throws Exception {
+    String rules =
+      "RULE:[1:$1@$0](.*@YAHOO\\.COM)s/@.*//\n" +
+      "RULE:[2:$1](johndoe)s/^.*$/guest/\n" +
+      "RULE:[2:$1;$2](^.*;admin$)s/;admin$//\n" +
+      "RULE:[2:$2](root)\n" +
+      "DEFAULT";
+    KerberosName.setRules(rules);
+    KerberosName.printRules();
+  }
+
+  private void checkTranslation(String from, String to) throws Exception {
+    System.out.println("Translate " + from);
+    KerberosName nm = new KerberosName(from);
+    String simple = nm.getShortName();
+    System.out.println("to " + simple);
+    assertEquals("short name incorrect", to, simple);
+  }
+
+  @Test
+  public void testRules() throws Exception {
+    checkTranslation("omalley@" + KerberosTestUtils.getRealm(), "omalley");
+    checkTranslation("hdfs/10.0.0.1@" + KerberosTestUtils.getRealm(), "hdfs");
+    checkTranslation("oom@YAHOO.COM", "oom");
+    checkTranslation("johndoe/zoo@FOO.COM", "guest");
+    checkTranslation("joe/admin@FOO.COM", "joe");
+    checkTranslation("joe/root@FOO.COM", "root");
+  }
+
+  private void checkBadName(String name) {
+    System.out.println("Checking " + name + " to ensure it is bad.");
+    try {
+      new KerberosName(name);
+      fail("didn't get exception for " + name);
+    } catch (IllegalArgumentException iae) {
+      // PASS
+    }
+  }
+
+  private void checkBadTranslation(String from) {
+    System.out.println("Checking bad translation for " + from);
+    KerberosName nm = new KerberosName(from);
+    try {
+      nm.getShortName();
+      fail("didn't get exception for " + from);
+    } catch (IOException ie) {
+      // PASS
+    }
+  }
+
+  @Test
+  public void testAntiPatterns() throws Exception {
+    checkBadName("owen/owen/owen@FOO.COM");
+    checkBadName("owen@foo/bar.com");
+    checkBadTranslation("foo@ACME.COM");
+    checkBadTranslation("root/joe@FOO.COM");
+  }
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestSigner.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestSigner.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestSigner.java (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/java/org/apache/hadoop/alfredo/util/TestSigner.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,93 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. See accompanying LICENSE file.
+ */
+package org.apache.hadoop.alfredo.util;
+
+import junit.framework.TestCase;
+
+public class TestSigner extends TestCase {
+
+  public void testNoSecret() throws Exception {
+    try {
+      new Signer(null);
+      fail();
+    }
+    catch (IllegalArgumentException ex) {
+    }
+  }
+
+  public void testNullAndEmptyString() throws Exception {
+    Signer signer = new Signer("secret".getBytes());
+    try {
+      signer.sign(null);
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+    try {
+      signer.sign("");
+      fail();
+    } catch (IllegalArgumentException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+  }
+
+  public void testSignature() throws Exception {
+    Signer signer = new Signer("secret".getBytes());
+    String s1 = signer.sign("ok");
+    String s2 = signer.sign("ok");
+    String s3 = signer.sign("wrong");
+    assertEquals(s1, s2);
+    assertNotSame(s1, s3);
+  }
+
+  public void testVerify() throws Exception {
+    Signer signer = new Signer("secret".getBytes());
+    String t = "test";
+    String s = signer.sign(t);
+    String e = signer.verifyAndExtract(s);
+    assertEquals(t, e);
+  }
+
+  public void testInvalidSignedText() throws Exception {
+    Signer signer = new Signer("secret".getBytes());
+    try {
+      signer.verifyAndExtract("test");
+      fail();
+    } catch (SignerException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+  }
+
+  public void testTampering() throws Exception {
+    Signer signer = new Signer("secret".getBytes());
+    String t = "test";
+    String s = signer.sign(t);
+    s += "x";
+    try {
+      signer.verifyAndExtract(s);
+      fail();
+    } catch (SignerException ex) {
+      // Expected
+    } catch (Throwable ex) {
+      fail();
+    }
+  }
+
+}

Added: hadoop/common/trunk/hadoop-alfredo/src/test/resources/krb5.conf
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-alfredo/src/test/resources/krb5.conf?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-alfredo/src/test/resources/krb5.conf (added)
+++ hadoop/common/trunk/hadoop-alfredo/src/test/resources/krb5.conf Fri Aug 19 22:31:06 2011
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+[libdefaults]
+	default_realm = ${kerberos.realm}
+	udp_preference_limit = 1
+	extra_addresses = 127.0.0.1
+[realms]
+	${kerberos.realm} = {
+		admin_server = localhost:88
+		kdc = localhost:88
+	}
+[domain_realm]
+	localhost = ${kerberos.realm}

Modified: hadoop/common/trunk/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/CHANGES.txt?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/trunk/hadoop-common/CHANGES.txt Fri Aug 19 22:31:06 2011
@@ -63,6 +63,9 @@ Trunk (unreleased changes)
     HADOOP-6385. dfs should support -rmdir (was HDFS-639). (Daryn Sharp
     via mattf)
 
+    HADOOP-7119. add Kerberos HTTP SPNEGO authentication support to Hadoop
+    JT/NN/DN/TT web-consoles. (Alejandro Abdelnur via atm)
+
   IMPROVEMENTS
 
     HADOOP-7042. Updates to test-patch.sh to include failed test names and

Modified: hadoop/common/trunk/hadoop-common/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/pom.xml?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/pom.xml (original)
+++ hadoop/common/trunk/hadoop-common/pom.xml Fri Aug 19 22:31:06 2011
@@ -237,6 +237,11 @@
       <artifactId>protobuf-java</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-alfredo</artifactId>
+      <scope>compile</scope>
+    </dependency>
   </dependencies>
 
   <build>

Added: hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/HttpAuthentication.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/HttpAuthentication.xml?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/HttpAuthentication.xml (added)
+++ hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/HttpAuthentication.xml Fri Aug 19 22:31:06 2011
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN"
+          "http://forrest.apache.org/dtd/document-v20.dtd">
+
+
+<document>
+
+  <header>
+    <title> 
+      Authentication for Hadoop HTTP web-consoles
+    </title>
+  </header>
+
+  <body>
+    <section>
+      <title> Introduction </title>
+      <p>
+        This document describes how to configure Hadoop HTTP web-consoles to require user
+        authentication. 
+      </p>
+      <p>
+        By default Hadoop HTTP web-consoles (JobTracker, NameNode, TaskTrackers and DataNodes) allow 
+        access without any form of authentication. 
+      </p>
+      <p>
+        Similarly to Hadoop RPC, Hadoop HTTP web-consoles can be configured to require Kerberos 
+        authentication using HTTP SPNEGO protocol (supported by browsers like Firefox and Internet
+        Explorer).        
+      </p>
+      <p>
+        In addition, Hadoop HTTP web-consoles support the equivalent of Hadoop's Pseudo/Simple
+        authentication. If this option is enabled, user must specify their user name in the first
+        browser interaction using the <code>user.name</code> query string parameter. For example:
+        <code>http://localhost:50030/jobtracker.jsp?user.name=babu</code>.
+      </p>
+      <p>
+        If a custom authentication mechanism is required for the HTTP web-consoles, it is possible 
+        to implement a plugin to support the alternate authentication mechanism (refer to 
+        Hadoop Alfredo for details on writing an <code>AuthenticatorHandler</code>).
+      </p>
+      <p>       
+        The next section describes how to configure Hadoop HTTP web-consoles to require user 
+        authentication.
+      </p>
+    </section>
+
+    <section> 
+      <title> Configuration </title>
+
+      <p>
+        The following properties should be in the <code>core-site.xml</code> of all the nodes
+        in the cluster.
+      </p>
+
+      <p><code>hadoop.http.filter.initializers</code>: add to this property the 
+      <code>org.apache.hadoop.security.AuthenticationFilterInitializer</code> initializer class.
+      </p>
+      
+      <p><code>hadoop.http.authentication.type</code>: Defines authentication used for the HTTP 
+      web-consoles. The supported values are: <code>simple | kerberos | 
+      #AUTHENTICATION_HANDLER_CLASSNAME#</code>. The dfeault value is <code>simple</code>.
+      </p>
+
+      <p><code>hadoop.http.authentication.token.validity</code>: Indicates how long (in seconds) 
+      an authentication token is valid before it has to be renewed. The default value is 
+      <code>36000</code>.
+      </p>
+
+      <p><code>hadoop.http.authentication.signature.secret</code>: The signature secret for  
+      signing the authentication tokens. If not set a random secret is generated at 
+      startup time. The same secret should be used for all nodes in the cluster, JobTracker, 
+      NameNode, DataNode and TastTracker. The default value is a <code>hadoop</code> value.
+      </p>
+        
+      <p><code>hadoop.http.authentication.cookie.domain</code>: The domain to use for the HTTP 
+      cookie that stores the authentication token. In order to authentiation to work 
+      correctly across all nodes in the cluster the domain must be correctly set.
+      There is no default value, the HTTP cookie will not have a domain working only
+      with the hostname issuing the HTTP cookie.
+      </p>
+
+      <p>
+      IMPORTANT: when using IP addresses, browsers ignore cookies with domain settings.
+      For this setting to work properly all nodes in the cluster must be configured
+      to generate URLs with hostname.domain names on it.
+      </p>
+
+      <p><code>hadoop.http.authentication.simple.anonymous.allowed</code>: Indicates if anonymous 
+      requests are allowed when using 'simple' authentication. The default value is 
+      <code>true</code>
+      </p>
+
+      <p><code>hadoop.http.authentication.kerberos.principal</code>: Indicates the Kerberos 
+      principal to be used for HTTP endpoint when using 'kerberos' authentication.
+      The principal short name must be <code>HTTP</code> per Kerberos HTTP SPENGO specification.
+      The default value is <code>HTTP/localhost@$LOCALHOST</code>.
+      </p>
+
+      <p><code>hadoop.http.authentication.kerberos.keytab</code>: Location of the keytab file 
+      with the credentials for the Kerberos principal used for the HTTP endpoint. 
+      The default value is <code>${user.home}/hadoop.keytab</code>.i
+      </p>
+
+    </section>
+
+  </body>
+</document>
+

Modified: hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/site.xml?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/site.xml (original)
+++ hadoop/common/trunk/hadoop-common/src/main/docs/src/documentation/content/xdocs/site.xml Fri Aug 19 22:31:06 2011
@@ -45,6 +45,7 @@ See http://forrest.apache.org/docs/linki
 		<SLA					 	label="Service Level Authorization" 	href="service_level_auth.html"/>
 		<native_lib    				label="Native Libraries" 					href="native_libraries.html" />
                 <superusers                      label="Superusers Acting On Behalf Of Other Users"     href="Superusers.html"/>
+    <http_authentication label="Authentication for Hadoop HTTP web-consoles" href="HttpAuthentication.html"/>
    </docs>
 
    <docs label="Miscellaneous"> 

Added: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationFilterInitializer.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationFilterInitializer.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationFilterInitializer.java (added)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationFilterInitializer.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.security;
+
+import org.apache.hadoop.alfredo.server.AuthenticationFilter;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.FilterContainer;
+import org.apache.hadoop.http.FilterInitializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Initializes Alfredo AuthenticationFilter which provides support for
+ * Kerberos HTTP SPENGO authentication.
+ * <p/>
+ * It enables anonymous access, simple/speudo and Kerberos HTTP SPNEGO
+ * authentication  for Hadoop JobTracker, NameNode, DataNodes and
+ * TaskTrackers.
+ * <p/>
+ * Refer to the <code>core-default.xml</code> file, after the comment
+ * 'HTTP Authentication' for details on the configuration options.
+ * All related configuration properties have 'hadoop.http.authentication.'
+ * as prefix.
+ */
+public class AuthenticationFilterInitializer extends FilterInitializer {
+
+  private static final String PREFIX = "hadoop.http.authentication.";
+
+  /**
+   * Initializes Alfredo AuthenticationFilter.
+   * <p/>
+   * Propagates to Alfredo AuthenticationFilter configuration all Hadoop
+   * configuration properties prefixed with "hadoop.http.authentication."
+   *
+   * @param container The filter container
+   * @param conf Configuration for run-time parameters
+   */
+  @Override
+  public void initFilter(FilterContainer container, Configuration conf) {
+    Map<String, String> filterConfig = new HashMap<String, String>();
+
+    //setting the cookie path to root '/' so it is used for all resources.
+    filterConfig.put(AuthenticationFilter.COOKIE_PATH, "/");
+
+    for (Map.Entry<String, String> entry : conf) {
+      String name = entry.getKey();
+      if (name.startsWith(PREFIX)) {
+        String value = conf.get(name);
+        name = name.substring(PREFIX.length());
+        filterConfig.put(name, value);
+      }
+    }
+
+    container.addFilter("authentication",
+                        AuthenticationFilter.class.getName(),
+                        filterConfig);
+  }
+
+}

Added: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java (added)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.security;
+
+import java.io.IOException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.alfredo.util.KerberosName;
+
+import sun.security.krb5.Config;
+import sun.security.krb5.KrbException;
+
+/**
+ * This class implements parsing and handling of Kerberos principal names. In 
+ * particular, it splits them apart and translates them down into local
+ * operating system names.
+ */
+@SuppressWarnings("all")
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+@InterfaceStability.Evolving
+public class HadoopKerberosName extends KerberosName {
+
+  static {
+    try {
+      Config.getInstance().getDefaultRealm();
+    } catch (KrbException ke) {
+      if(UserGroupInformation.isSecurityEnabled())
+        throw new IllegalArgumentException("Can't get Kerberos configuration",ke);
+    }
+  }
+
+  /**
+   * Create a name from the full Kerberos principal name.
+   * @param name
+   */
+  public HadoopKerberosName(String name) {
+    super(name);
+  }
+  /**
+   * Set the static configuration to get the rules.
+   * @param conf the new configuration
+   * @throws IOException
+   */
+  public static void setConfiguration(Configuration conf) throws IOException {
+    String ruleString = conf.get("hadoop.security.auth_to_local", "DEFAULT");
+    setRules(ruleString);
+  }
+
+  public static void main(String[] args) throws Exception {
+    setConfiguration(new Configuration());
+    for(String arg: args) {
+      HadoopKerberosName name = new HadoopKerberosName(arg);
+      System.out.println("Name: " + name + " to " + name.getShortName());
+    }
+  }
+}

Modified: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java (original)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java Fri Aug 19 22:31:06 2011
@@ -290,7 +290,7 @@ public class SecurityUtil {
    * @return host name if the the string conforms to the above format, else null
    */
   public static String getHostFromPrincipal(String principalName) {
-    return new KerberosName(principalName).getHostName();
+    return new HadoopKerberosName(principalName).getHostName();
   }
 
   private static ServiceLoader<SecurityInfo> securityInfoProviders = 

Modified: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/User.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/User.java?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/User.java (original)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/User.java Fri Aug 19 22:31:06 2011
@@ -45,7 +45,7 @@ class User implements Principal {
   
   public User(String name, AuthenticationMethod authMethod, LoginContext login) {
     try {
-      shortName = new KerberosName(name).getShortName();
+      shortName = new HadoopKerberosName(name).getShortName();
     } catch (IOException ioe) {
       throw new IllegalArgumentException("Illegal principal name " + name, ioe);
     }

Modified: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java (original)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java Fri Aug 19 22:31:06 2011
@@ -194,7 +194,7 @@ public class UserGroupInformation {
     initUGI(conf);
     // give the configuration on how to translate Kerberos names
     try {
-      KerberosName.setConfiguration(conf);
+      HadoopKerberosName.setConfiguration(conf);
     } catch (IOException ioe) {
       throw new RuntimeException("Problem with Kerberos auth_to_local name " +
           "configuration", ioe);

Modified: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenIdentifier.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenIdentifier.java?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenIdentifier.java (original)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenIdentifier.java Fri Aug 19 22:31:06 2011
@@ -27,7 +27,7 @@ import java.io.IOException;
 
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.io.WritableUtils;
-import org.apache.hadoop.security.KerberosName;
+import org.apache.hadoop.security.HadoopKerberosName;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.TokenIdentifier;
 
@@ -58,7 +58,7 @@ extends TokenIdentifier {
     if (renewer == null) {
       this.renewer = new Text();
     } else {
-      KerberosName renewerKrbName = new KerberosName(renewer.toString());
+      HadoopKerberosName renewerKrbName = new HadoopKerberosName(renewer.toString());
       try {
         this.renewer = new Text(renewerKrbName.getShortName());
       } catch (IOException e) {

Modified: hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenSecretManager.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenSecretManager.java?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenSecretManager.java (original)
+++ hadoop/common/trunk/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/AbstractDelegationTokenSecretManager.java Fri Aug 19 22:31:06 2011
@@ -35,11 +35,10 @@ import javax.crypto.SecretKey;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.security.AccessControlException;
-import org.apache.hadoop.security.KerberosName;
+import org.apache.hadoop.security.HadoopKerberosName;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager;
 import org.apache.hadoop.util.Daemon;
-import org.apache.hadoop.util.StringUtils;
 
 @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
 @InterfaceStability.Evolving
@@ -284,7 +283,7 @@ extends AbstractDelegationTokenIdentifie
     }
     String owner = id.getUser().getUserName();
     Text renewer = id.getRenewer();
-    KerberosName cancelerKrbName = new KerberosName(canceller);
+    HadoopKerberosName cancelerKrbName = new HadoopKerberosName(canceller);
     String cancelerShortName = cancelerKrbName.getShortName();
     if (!canceller.equals(owner)
         && (renewer == null || "".equals(renewer.toString()) || !cancelerShortName

Modified: hadoop/common/trunk/hadoop-common/src/main/resources/core-default.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/main/resources/core-default.xml?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/main/resources/core-default.xml (original)
+++ hadoop/common/trunk/hadoop-common/src/main/resources/core-default.xml Fri Aug 19 22:31:06 2011
@@ -782,4 +782,73 @@
   </description>
 </property>
 
+<!-- HTTP web-consoles Authentication -->
+
+<property>
+  <name>hadoop.http.authentication.type</name>
+  <value>simple</value>
+  <description>
+    Defines authentication used for Oozie HTTP endpoint.
+    Supported values are: simple | kerberos | #AUTHENTICATION_HANDLER_CLASSNAME#
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.token.validity</name>
+  <value>36000</value>
+  <description>
+    Indicates how long (in seconds) an authentication token is valid before it has
+    to be renewed.
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.signature.secret</name>
+  <value>hadoop</value>
+  <description>
+    The signature secret for signing the authentication tokens.
+    If not set a random secret is generated at startup time.
+    The same secret should be used for JT/NN/DN/TT configurations.
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.cookie.domain</name>
+  <value></value>
+  <description>
+    The domain to use for the HTTP cookie that stores the authentication token.
+    In order to authentiation to work correctly across all Hadoop nodes web-consoles
+    the domain must be correctly set.
+    IMPORTANT: when using IP addresses, browsers ignore cookies with domain settings.
+    For this setting to work properly all nodes in the cluster must be configured
+    to generate URLs with hostname.domain names on it.
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.simple.anonymous.allowed</name>
+  <value>true</value>
+  <description>
+    Indicates if anonymous requests are allowed when using 'simple' authentication.
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.kerberos.principal</name>
+  <value>HTTP/localhost@LOCALHOST</value>
+  <description>
+    Indicates the Kerberos principal to be used for HTTP endpoint.
+    The principal MUST start with 'HTTP/' as per Kerberos HTTP SPNEGO specification.
+  </description>
+</property>
+
+<property>
+  <name>hadoop.http.authentication.kerberos.keytab</name>
+  <value>${user.home}/hadoop.keytab</value>
+  <description>
+    Location of the keytab file with the credentials for the principal.
+    Referring to the same keytab file Oozie uses for its Kerberos credentials for Hadoop.
+  </description>
+</property>
+
 </configuration>

Added: hadoop/common/trunk/hadoop-common/src/test/java/org/apache/hadoop/security/TestAuthenticationFilter.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-common/src/test/java/org/apache/hadoop/security/TestAuthenticationFilter.java?rev=1159804&view=auto
==============================================================================
--- hadoop/common/trunk/hadoop-common/src/test/java/org/apache/hadoop/security/TestAuthenticationFilter.java (added)
+++ hadoop/common/trunk/hadoop-common/src/test/java/org/apache/hadoop/security/TestAuthenticationFilter.java Fri Aug 19 22:31:06 2011
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.hadoop.security;
+
+
+import junit.framework.TestCase;
+import org.apache.hadoop.alfredo.server.AuthenticationFilter;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.FilterContainer;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Map;
+
+public class TestAuthenticationFilter extends TestCase {
+
+  @SuppressWarnings("unchecked")
+  public void testConfiguration() {
+    Configuration conf = new Configuration();
+    conf.set("hadoop.http.authentication.foo", "bar");
+
+    FilterContainer container = Mockito.mock(FilterContainer.class);
+    Mockito.doAnswer(
+      new Answer() {
+        public Object answer(InvocationOnMock invocationOnMock)
+          throws Throwable {
+          Object[] args = invocationOnMock.getArguments();
+
+          assertEquals("authentication", args[0]);
+
+          assertEquals(AuthenticationFilter.class.getName(), args[1]);
+
+          Map<String, String> conf = (Map<String, String>) args[2];
+          assertEquals("/", conf.get("cookie.path"));
+
+          assertEquals("simple", conf.get("type"));
+          assertEquals("36000", conf.get("token.validity"));
+          assertEquals("hadoop", conf.get("signature.secret"));
+          assertNull(conf.get("cookie.domain"));
+          assertEquals("true", conf.get("simple.anonymous.allowed"));
+          assertEquals("HTTP/localhost@LOCALHOST",
+                       conf.get("kerberos.principal"));
+          assertEquals(System.getProperty("user.home") +
+                       "/hadoop.keytab", conf.get("kerberos.keytab"));
+          assertEquals("bar", conf.get("foo"));
+
+          return null;
+        }
+      }
+    ).when(container).addFilter(Mockito.<String>anyObject(),
+                                Mockito.<String>anyObject(),
+                                Mockito.<Map<String, String>>anyObject());
+
+    new AuthenticationFilterInitializer().initFilter(container, conf);
+  }
+
+}

Modified: hadoop/common/trunk/hadoop-project/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-project/pom.xml?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-project/pom.xml (original)
+++ hadoop/common/trunk/hadoop-project/pom.xml Fri Aug 19 22:31:06 2011
@@ -104,6 +104,11 @@
         <version>${project.version}</version>
         <type>test-jar</type>
       </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-alfredo</artifactId>
+        <version>${project.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>com.google.guava</groupId>
@@ -468,6 +473,16 @@
           <artifactId>jspc-maven-plugin</artifactId>
           <version>2.0-alpha-3</version>
         </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>2.1.1</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-project-info-reports-plugin</artifactId>
+          <version>2.4</version>
+        </plugin>
       </plugins>
     </pluginManagement>
 

Modified: hadoop/common/trunk/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/pom.xml?rev=1159804&r1=1159803&r2=1159804&view=diff
==============================================================================
--- hadoop/common/trunk/pom.xml (original)
+++ hadoop/common/trunk/pom.xml Fri Aug 19 22:31:06 2011
@@ -38,6 +38,7 @@
     <module>hadoop-project-distro</module>
     <module>hadoop-assemblies</module>
     <module>hadoop-annotations</module>
+    <module>hadoop-alfredo</module>
     <module>hadoop-common</module>
     <module>hadoop-hdfs</module>
   </modules>