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>