Przeglądaj źródła

HADOOP-10911. hadoop.auth cookie after HADOOP-10710 still not proper according to RFC2109. (gchanan via tucu)

Alejandro Abdelnur 10 lat temu
rodzic
commit
156e6a4f8a

+ 10 - 0
hadoop-common-project/hadoop-auth/pom.xml

@@ -61,6 +61,16 @@
       <groupId>org.mortbay.jetty</groupId>
       <artifactId>jetty</artifactId>
       <scope>test</scope>
+    </dependency>
+     <dependency>
+      <groupId>org.apache.tomcat.embed</groupId>
+      <artifactId>tomcat-embed-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat.embed</groupId>
+      <artifactId>tomcat-embed-logging-juli</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>

+ 1 - 3
hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java

@@ -519,9 +519,7 @@ public class AuthenticationFilter implements Filter {
     StringBuilder sb = new StringBuilder(AuthenticatedURL.AUTH_COOKIE)
                            .append("=");
     if (token != null && token.length() > 0) {
-      sb.append("\"")
-          .append(token)
-          .append("\"");
+      sb.append(token);
     }
     sb.append("; Version=1");
 

+ 133 - 4
hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java

@@ -13,7 +13,22 @@
  */
 package org.apache.hadoop.security.authentication.client;
 
+import org.apache.catalina.deploy.FilterDef;
+import org.apache.catalina.deploy.FilterMap;
+import org.apache.catalina.startup.Tomcat;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.params.AuthPolicy;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
+import org.apache.http.impl.client.SystemDefaultHttpClient;
+import org.apache.http.util.EntityUtils;
 import org.mortbay.jetty.Server;
 import org.mortbay.jetty.servlet.Context;
 import org.mortbay.jetty.servlet.FilterHolder;
@@ -24,16 +39,19 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.io.Writer;
 import java.net.HttpURLConnection;
 import java.net.ServerSocket;
 import java.net.URL;
+import java.security.Principal;
 import java.util.Properties;
 import org.junit.Assert;
 
@@ -41,10 +59,18 @@ public class AuthenticatorTestCase {
   private Server server;
   private String host = null;
   private int port = -1;
+  private boolean useTomcat = false;
+  private Tomcat tomcat = null;
   Context context;
 
   private static Properties authenticatorConfig;
 
+  public AuthenticatorTestCase() {}
+
+  public AuthenticatorTestCase(boolean useTomcat) {
+    this.useTomcat = useTomcat;
+  }
+
   protected static void setAuthenticationHandlerConfig(Properties config) {
     authenticatorConfig = config;
   }
@@ -80,7 +106,19 @@ public class AuthenticatorTestCase {
     }
   }
 
+  protected int getLocalPort() throws Exception {
+    ServerSocket ss = new ServerSocket(0);
+    int ret = ss.getLocalPort();
+    ss.close();
+    return ret;
+  }
+
   protected void start() throws Exception {
+    if (useTomcat) startTomcat();
+    else startJetty();
+  }
+
+  protected void startJetty() throws Exception {
     server = new Server(0);
     context = new Context();
     context.setContextPath("/foo");
@@ -88,16 +126,42 @@ public class AuthenticatorTestCase {
     context.addFilter(new FilterHolder(TestFilter.class), "/*", 0);
     context.addServlet(new ServletHolder(TestServlet.class), "/bar");
     host = "localhost";
-    ServerSocket ss = new ServerSocket(0);
-    port = ss.getLocalPort();
-    ss.close();
+    port = getLocalPort();
     server.getConnectors()[0].setHost(host);
     server.getConnectors()[0].setPort(port);
     server.start();
     System.out.println("Running embedded servlet container at: http://" + host + ":" + port);
   }
 
+  protected void startTomcat() throws Exception {
+    tomcat = new Tomcat();
+    File base = new File(System.getProperty("java.io.tmpdir"));
+    org.apache.catalina.Context ctx =
+      tomcat.addContext("/foo",base.getAbsolutePath());
+    FilterDef fd = new FilterDef();
+    fd.setFilterClass(TestFilter.class.getName());
+    fd.setFilterName("TestFilter");
+    FilterMap fm = new FilterMap();
+    fm.setFilterName("TestFilter");
+    fm.addURLPattern("/*");
+    fm.addServletName("/bar");
+    ctx.addFilterDef(fd);
+    ctx.addFilterMap(fm);
+    tomcat.addServlet(ctx, "/bar", TestServlet.class.getName());
+    ctx.addServletMapping("/bar", "/bar");
+    host = "localhost";
+    port = getLocalPort();
+    tomcat.setHostname(host);
+    tomcat.setPort(port);
+    tomcat.start();
+  }
+
   protected void stop() throws Exception {
+    if (useTomcat) stopTomcat();
+    else stopJetty();
+  }
+
+  protected void stopJetty() throws Exception {
     try {
       server.stop();
     } catch (Exception e) {
@@ -109,6 +173,18 @@ public class AuthenticatorTestCase {
     }
   }
 
+  protected void stopTomcat() throws Exception {
+    try {
+      tomcat.stop();
+    } catch (Exception e) {
+    }
+
+    try {
+      tomcat.destroy();
+    } catch (Exception e) {
+    }
+  }
+
   protected String getBaseURL() {
     return "http://" + host + ":" + port + "/foo/bar";
   }
@@ -165,4 +241,57 @@ public class AuthenticatorTestCase {
     }
   }
 
+  private SystemDefaultHttpClient getHttpClient() {
+    final SystemDefaultHttpClient httpClient = new SystemDefaultHttpClient();
+    httpClient.getAuthSchemes().register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory(true));
+     Credentials use_jaas_creds = new Credentials() {
+       public String getPassword() {
+         return null;
+       }
+
+       public Principal getUserPrincipal() {
+         return null;
+       }
+     };
+
+     httpClient.getCredentialsProvider().setCredentials(
+       AuthScope.ANY, use_jaas_creds);
+     return httpClient;
+  }
+
+  private void doHttpClientRequest(HttpClient httpClient, HttpUriRequest request) throws Exception {
+    HttpResponse response = null;
+    try {
+      response = httpClient.execute(request);
+      final int httpStatus = response.getStatusLine().getStatusCode();
+      Assert.assertEquals(HttpURLConnection.HTTP_OK, httpStatus);
+    } finally {
+      if (response != null) EntityUtils.consumeQuietly(response.getEntity());
+    }
+  }
+
+  protected void _testAuthenticationHttpClient(Authenticator authenticator, boolean doPost) throws Exception {
+    start();
+    try {
+      SystemDefaultHttpClient httpClient = getHttpClient();
+      doHttpClientRequest(httpClient, new HttpGet(getBaseURL()));
+
+      // Always do a GET before POST to trigger the SPNego negotiation
+      if (doPost) {
+        HttpPost post = new HttpPost(getBaseURL());
+        byte [] postBytes = POST.getBytes();
+        ByteArrayInputStream bis = new ByteArrayInputStream(postBytes);
+        InputStreamEntity entity = new InputStreamEntity(bis, postBytes.length);
+
+        // Important that the entity is not repeatable -- this means if
+        // we have to renegotiate (e.g. b/c the cookie wasn't handled properly)
+        // the test will fail.
+        Assert.assertFalse(entity.isRepeatable());
+        post.setEntity(entity);
+        doHttpClientRequest(httpClient, post);
+      }
+    } finally {
+      stop();
+    }
+  }
 }

+ 53 - 5
hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/TestKerberosAuthenticator.java

@@ -20,16 +20,36 @@ import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHand
 import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runner.RunWith;
 import org.junit.Test;
 
 import java.io.File;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Properties;
 import java.util.concurrent.Callable;
 
+@RunWith(Parameterized.class)
 public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
+  private boolean useTomcat = false;
+
+  public TestKerberosAuthenticator(boolean useTomcat) {
+    this.useTomcat = useTomcat;
+  }
+
+  @Parameterized.Parameters
+  public static Collection booleans() {
+    return Arrays.asList(new Object[][] {
+      { false },
+      { true }
+    });
+  }
+
   @Before
   public void setup() throws Exception {
     // create keytab
@@ -53,7 +73,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
   @Test(timeout=60000)
   public void testFallbacktoPseudoAuthenticator() throws Exception {
-    AuthenticatorTestCase auth = new AuthenticatorTestCase();
+    AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
     Properties props = new Properties();
     props.setProperty(AuthenticationFilter.AUTH_TYPE, "simple");
     props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "false");
@@ -63,7 +83,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
   @Test(timeout=60000)
   public void testFallbacktoPseudoAuthenticatorAnonymous() throws Exception {
-    AuthenticatorTestCase auth = new AuthenticatorTestCase();
+    AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
     Properties props = new Properties();
     props.setProperty(AuthenticationFilter.AUTH_TYPE, "simple");
     props.setProperty(PseudoAuthenticationHandler.ANONYMOUS_ALLOWED, "true");
@@ -73,7 +93,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
   @Test(timeout=60000)
   public void testNotAuthenticated() throws Exception {
-    AuthenticatorTestCase auth = new AuthenticatorTestCase();
+    AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
     AuthenticatorTestCase.setAuthenticationHandlerConfig(getAuthenticationHandlerConfiguration());
     auth.start();
     try {
@@ -89,7 +109,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
   @Test(timeout=60000)
   public void testAuthentication() throws Exception {
-    final AuthenticatorTestCase auth = new AuthenticatorTestCase();
+    final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
     AuthenticatorTestCase.setAuthenticationHandlerConfig(
             getAuthenticationHandlerConfiguration());
     KerberosTestUtils.doAsClient(new Callable<Void>() {
@@ -103,7 +123,7 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
 
   @Test(timeout=60000)
   public void testAuthenticationPost() throws Exception {
-    final AuthenticatorTestCase auth = new AuthenticatorTestCase();
+    final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
     AuthenticatorTestCase.setAuthenticationHandlerConfig(
             getAuthenticationHandlerConfiguration());
     KerberosTestUtils.doAsClient(new Callable<Void>() {
@@ -114,4 +134,32 @@ public class TestKerberosAuthenticator extends KerberosSecurityTestcase {
       }
     });
   }
+
+  @Test(timeout=60000)
+  public void testAuthenticationHttpClient() throws Exception {
+    final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
+    AuthenticatorTestCase.setAuthenticationHandlerConfig(
+            getAuthenticationHandlerConfiguration());
+    KerberosTestUtils.doAsClient(new Callable<Void>() {
+      @Override
+      public Void call() throws Exception {
+        auth._testAuthenticationHttpClient(new KerberosAuthenticator(), false);
+        return null;
+      }
+    });
+  }
+
+  @Test(timeout=60000)
+  public void testAuthenticationHttpClientPost() throws Exception {
+    final AuthenticatorTestCase auth = new AuthenticatorTestCase(useTomcat);
+    AuthenticatorTestCase.setAuthenticationHandlerConfig(
+            getAuthenticationHandlerConfiguration());
+    KerberosTestUtils.doAsClient(new Callable<Void>() {
+      @Override
+      public Void call() throws Exception {
+        auth._testAuthenticationHttpClient(new KerberosAuthenticator(), true);
+        return null;
+      }
+    });
+  }
 }

+ 3 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -710,6 +710,9 @@ Release 2.6.0 - UNRELEASED
       loaded. (umamahesh)      
     --
 
+    HADOOP-10911. hadoop.auth cookie after HADOOP-10710 still not proper
+    according to RFC2109. (gchanan via tucu)
+
 Release 2.5.1 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 10 - 0
hadoop-project/pom.xml

@@ -398,6 +398,16 @@
         <artifactId>jetty-util</artifactId>
         <version>6.1.26</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-core</artifactId>
+        <version>7.0.55</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-logging-juli</artifactId>
+        <version>7.0.55</version>
+      </dependency>
       <dependency>
         <groupId>javax.servlet.jsp</groupId>
         <artifactId>jsp-api</artifactId>