瀏覽代碼

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 13 年之前
父節點
當前提交
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
     HADOOP-8085. Add RPC metrics to ProtobufRpcEngine. (Hari Mankude via
     suresh)
     suresh)
 
 
+    HADOOP-8098. KerberosAuthenticatorHandler should use _HOST replacement to 
+    resolve principal name (tucu)
+
   OPTIMIZATIONS
   OPTIMIZATIONS
 
 
   BUG FIXES
   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 
       <p><code>hadoop.http.authentication.kerberos.principal</code>: Indicates the Kerberos 
       principal to be used for HTTP endpoint when using 'kerberos' authentication.
       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 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>
 
 
       <p><code>hadoop.http.authentication.kerberos.keytab</code>: Location of the keytab file 
       <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";
   public static final String CONF_CONTEXT_ATTRIBUTE = "hadoop.conf";
   static final String ADMINS_ACL = "admins.acl";
   static final String ADMINS_ACL = "admins.acl";
 
 
+  public static final String BIND_ADDRESS = "bind.address";
+
   private AccessControlList adminsAcl;
   private AccessControlList adminsAcl;
 
 
   protected final Server webServer;
   protected final Server webServer;
@@ -243,6 +245,8 @@ public class HttpServer implements FilterContainer {
     addGlobalFilter("safety", QuotingInputFilter.class.getName(), null);
     addGlobalFilter("safety", QuotingInputFilter.class.getName(), null);
     final FilterInitializer[] initializers = getFilterInitializers(conf); 
     final FilterInitializer[] initializers = getFilterInitializers(conf); 
     if (initializers != null) {
     if (initializers != null) {
+      conf = new Configuration(conf);
+      conf.set(BIND_ADDRESS, bindAddress);
       for(FilterInitializer c : initializers) {
       for(FilterInitializer c : initializers) {
         c.initFilter(this, conf);
         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;
 package org.apache.hadoop.security;
 
 
+import org.apache.hadoop.http.HttpServer;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.http.FilterContainer;
 import org.apache.hadoop.http.FilterContainer;
 import org.apache.hadoop.http.FilterInitializer;
 import org.apache.hadoop.http.FilterInitializer;
+import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
 
 
 import java.io.FileReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.IOException;
@@ -46,7 +48,7 @@ public class AuthenticationFilterInitializer extends FilterInitializer {
   static final String PREFIX = "hadoop.http.authentication.";
   static final String PREFIX = "hadoop.http.authentication.";
 
 
   static final String SIGNATURE_SECRET_FILE = AuthenticationFilter.SIGNATURE_SECRET + ".file";
   static final String SIGNATURE_SECRET_FILE = AuthenticationFilter.SIGNATURE_SECRET + ".file";
-  
+
   /**
   /**
    * Initializes hadoop-auth AuthenticationFilter.
    * Initializes hadoop-auth AuthenticationFilter.
    * <p/>
    * <p/>
@@ -90,7 +92,20 @@ public class AuthenticationFilterInitializer extends FilterInitializer {
     } catch (IOException ex) {
     } catch (IOException ex) {
       throw new RuntimeException("Could not read HTTP signature secret file: " + signatureSecretFile);            
       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",
     container.addFilter("authentication",
                         AuthenticationFilter.class.getName(),
                         AuthenticationFilter.class.getName(),
                         filterConfig);
                         filterConfig);

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

@@ -833,7 +833,7 @@
 
 
 <property>
 <property>
   <name>hadoop.http.authentication.kerberos.principal</name>
   <name>hadoop.http.authentication.kerberos.principal</name>
-  <value>HTTP/localhost@LOCALHOST</value>
+  <value>HTTP/_HOST@LOCALHOST</value>
   <description>
   <description>
     Indicates the Kerberos principal to be used for HTTP endpoint.
     Indicates the Kerberos principal to be used for HTTP endpoint.
     The principal MUST start with 'HTTP/' as per Kerberos HTTP SPNEGO specification.
     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 junit.framework.TestCase;
+import org.apache.hadoop.http.HttpServer;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.http.FilterContainer;
 import org.apache.hadoop.http.FilterContainer;
+import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
 import org.mockito.Mockito;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.mockito.stubbing.Answer;
@@ -48,6 +50,8 @@ public class TestAuthenticationFilter extends TestCase {
              AuthenticationFilterInitializer.SIGNATURE_SECRET_FILE, 
              AuthenticationFilterInitializer.SIGNATURE_SECRET_FILE, 
              secretFile.getAbsolutePath());
              secretFile.getAbsolutePath());
 
 
+    conf.set(HttpServer.BIND_ADDRESS, "barhost");
+    
     FilterContainer container = Mockito.mock(FilterContainer.class);
     FilterContainer container = Mockito.mock(FilterContainer.class);
     Mockito.doAnswer(
     Mockito.doAnswer(
       new Answer() {
       new Answer() {
@@ -67,7 +71,7 @@ public class TestAuthenticationFilter extends TestCase {
           assertEquals("hadoop", conf.get("signature.secret"));
           assertEquals("hadoop", conf.get("signature.secret"));
           assertNull(conf.get("cookie.domain"));
           assertNull(conf.get("cookie.domain"));
           assertEquals("true", conf.get("simple.anonymous.allowed"));
           assertEquals("true", conf.get("simple.anonymous.allowed"));
-          assertEquals("HTTP/localhost@LOCALHOST",
+          assertEquals("HTTP/barhost@LOCALHOST",
                        conf.get("kerberos.principal"));
                        conf.get("kerberos.principal"));
           assertEquals(System.getProperty("user.home") +
           assertEquals(System.getProperty("user.home") +
                        "/hadoop.keytab", conf.get("kerberos.keytab"));
                        "/hadoop.keytab", conf.get("kerberos.keytab"));