Explorar o código

HADOOP-8098. KerberosAuthenticatorHandler should use _HOST replacement to resolve principal name (tucu)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1294757 13f79535-47bb-0310-9956-ffa450edef68
Alejandro Abdelnur %!s(int64=13) %!d(string=hai) anos
pai
achega
e43656c711

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

@@ -154,6 +154,9 @@ Release 0.23.3 - UNRELEASED
     HADOOP-8085. Add RPC metrics to ProtobufRpcEngine. (Hari Mankude via
     suresh)
 
+    HADOOP-8098. KerberosAuthenticatorHandler should use _HOST replacement to 
+    resolve principal name (tucu)
+
   OPTIMIZATIONS
 
   BUG FIXES

+ 2 - 1
hadoop-common-project/hadoop-common/src/main/docs/src/documentation/content/xdocs/HttpAuthentication.xml

@@ -111,7 +111,8 @@
       <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>.
+      The default value is <code>HTTP/_HOST@$LOCALHOST</code>, where <code>_HOST</code> -if present-
+      is replaced with bind address of the HTTP server.
       </p>
 
       <p><code>hadoop.http.authentication.kerberos.keytab</code>: Location of the keytab file 

+ 4 - 0
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer.java

@@ -100,6 +100,8 @@ public class HttpServer implements FilterContainer {
   public static final String CONF_CONTEXT_ATTRIBUTE = "hadoop.conf";
   static final String ADMINS_ACL = "admins.acl";
 
+  public static final String BIND_ADDRESS = "bind.address";
+
   private AccessControlList adminsAcl;
 
   protected final Server webServer;
@@ -243,6 +245,8 @@ public class HttpServer implements FilterContainer {
     addGlobalFilter("safety", QuotingInputFilter.class.getName(), null);
     final FilterInitializer[] initializers = getFilterInitializers(conf); 
     if (initializers != null) {
+      conf = new Configuration(conf);
+      conf.set(BIND_ADDRESS, bindAddress);
       for(FilterInitializer c : initializers) {
         c.initFilter(this, conf);
       }

+ 17 - 2
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/AuthenticationFilterInitializer.java

@@ -17,10 +17,12 @@
  */
 package org.apache.hadoop.security;
 
+import org.apache.hadoop.http.HttpServer;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.http.FilterContainer;
 import org.apache.hadoop.http.FilterInitializer;
+import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
 
 import java.io.FileReader;
 import java.io.IOException;
@@ -46,7 +48,7 @@ public class AuthenticationFilterInitializer extends FilterInitializer {
   static final String PREFIX = "hadoop.http.authentication.";
 
   static final String SIGNATURE_SECRET_FILE = AuthenticationFilter.SIGNATURE_SECRET + ".file";
-  
+
   /**
    * Initializes hadoop-auth AuthenticationFilter.
    * <p/>
@@ -90,7 +92,20 @@ public class AuthenticationFilterInitializer extends FilterInitializer {
     } catch (IOException ex) {
       throw new RuntimeException("Could not read HTTP signature secret file: " + signatureSecretFile);            
     }
-    
+
+    //Resolve _HOST into bind address
+    String bindAddress = conf.get(HttpServer.BIND_ADDRESS);
+    String principal = filterConfig.get(KerberosAuthenticationHandler.PRINCIPAL);
+    if (principal != null) {
+      try {
+        principal = SecurityUtil.getServerPrincipal(principal, bindAddress);
+      }
+      catch (IOException ex) {
+        throw new RuntimeException("Could not resolve Kerberos principal name: " + ex.toString(), ex);
+      }
+      filterConfig.put(KerberosAuthenticationHandler.PRINCIPAL, principal);
+    }
+
     container.addFilter("authentication",
                         AuthenticationFilter.class.getName(),
                         filterConfig);

+ 1 - 1
hadoop-common-project/hadoop-common/src/main/resources/core-default.xml

@@ -833,7 +833,7 @@
 
 <property>
   <name>hadoop.http.authentication.kerberos.principal</name>
-  <value>HTTP/localhost@LOCALHOST</value>
+  <value>HTTP/_HOST@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.

+ 5 - 1
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestAuthenticationFilter.java

@@ -18,9 +18,11 @@ package org.apache.hadoop.security;
 
 
 import junit.framework.TestCase;
+import org.apache.hadoop.http.HttpServer;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.http.FilterContainer;
+import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -48,6 +50,8 @@ public class TestAuthenticationFilter extends TestCase {
              AuthenticationFilterInitializer.SIGNATURE_SECRET_FILE, 
              secretFile.getAbsolutePath());
 
+    conf.set(HttpServer.BIND_ADDRESS, "barhost");
+    
     FilterContainer container = Mockito.mock(FilterContainer.class);
     Mockito.doAnswer(
       new Answer() {
@@ -67,7 +71,7 @@ public class TestAuthenticationFilter extends TestCase {
           assertEquals("hadoop", conf.get("signature.secret"));
           assertNull(conf.get("cookie.domain"));
           assertEquals("true", conf.get("simple.anonymous.allowed"));
-          assertEquals("HTTP/localhost@LOCALHOST",
+          assertEquals("HTTP/barhost@LOCALHOST",
                        conf.get("kerberos.principal"));
           assertEquals(System.getProperty("user.home") +
                        "/hadoop.keytab", conf.get("kerberos.keytab"));