Browse Source

HADOOP-13890. Maintain HTTP/host as SPNEGO SPN support and fix KerberosName parsing. Contributed by Xiaoyu Yao.

(cherry picked from commit f5e0bd30fde654ed48fe73e5c0523030365385a4)
(cherry picked from commit 85083567be22eba76dbf1f8c18149a0493f07526)
Xiaoyu Yao 8 years ago
parent
commit
691a32c6f6

+ 10 - 9
hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java

@@ -73,7 +73,7 @@ import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
  * </ul>
  */
 public class KerberosAuthenticationHandler implements AuthenticationHandler {
-  private static final Logger LOG = LoggerFactory.getLogger(
+  public static final Logger LOG = LoggerFactory.getLogger(
       KerberosAuthenticationHandler.class);
 
   /**
@@ -274,14 +274,14 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
         loginContexts.add(loginContext);
         KerberosName kerbName = new KerberosName(spnegoPrincipal);
         if (kerbName.getHostName() != null
-            && kerbName.getRealm() != null
             && kerbName.getServiceName() != null
             && kerbName.getServiceName().equals("HTTP")) {
-          LOG.trace("Map server: {} to principal: {}", kerbName.getHostName(),
+          boolean added = serverPrincipalMap.put(kerbName.getHostName(),
               spnegoPrincipal);
-          serverPrincipalMap.put(kerbName.getHostName(), spnegoPrincipal);
+          LOG.info("Map server: {} to principal: [{}], added = {}",
+              kerbName.getHostName(), spnegoPrincipal, added);
         } else {
-          LOG.warn("HTTP principal: {} is invalid for SPNEGO!",
+          LOG.warn("HTTP principal: [{}] is invalid for SPNEGO!",
               spnegoPrincipal);
         }
       }
@@ -419,8 +419,8 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
               @Override
               public AuthenticationToken run() throws Exception {
                 if (LOG.isTraceEnabled()) {
-                  LOG.trace("SPNEGO with principals: {}",
-                      serverPrincipals.toString());
+                  LOG.trace("SPNEGO with server principals: {} for {}",
+                      serverPrincipals.toString(), serverName);
                 }
                 AuthenticationToken token = null;
                 Exception lastException = null;
@@ -464,7 +464,7 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
     GSSCredential gssCreds = null;
     AuthenticationToken token = null;
     try {
-      LOG.trace("SPNEGO initiated with principal {}", serverPrincipal);
+      LOG.trace("SPNEGO initiated with server principal [{}]", serverPrincipal);
       gssCreds = this.gssManager.createCredential(
           this.gssManager.createName(serverPrincipal,
               KerberosUtil.getOidInstance("NT_GSS_KRB5_PRINCIPAL")),
@@ -491,7 +491,8 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
         String userName = kerberosName.getShortName();
         token = new AuthenticationToken(userName, clientPrincipal, getType());
         response.setStatus(HttpServletResponse.SC_OK);
-        LOG.trace("SPNEGO completed for principal [{}]", clientPrincipal);
+        LOG.trace("SPNEGO completed for client principal [{}]",
+            clientPrincipal);
       }
     } finally {
       if (gssContext != null) {

+ 2 - 2
hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java

@@ -54,7 +54,7 @@ public class KerberosName {
    * A pattern that matches a Kerberos name with at most 2 components.
    */
   private static final Pattern nameParser =
-    Pattern.compile("([^/@]*)(/([^/@]*))?@([^/@]*)");
+      Pattern.compile("([^/@]+)(/([^/@]+))?(@([^/@]+))?");
 
   /**
    * A pattern that matches a string with out '$' and then a single
@@ -118,7 +118,7 @@ public class KerberosName {
     } else {
       serviceName = match.group(1);
       hostName = match.group(3);
-      realm = match.group(4);
+      realm = match.group(5);
     }
   }
 

+ 22 - 0
hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/util/TestKerberosName.java

@@ -82,6 +82,28 @@ public class TestKerberosName {
     checkTranslation("root/joe@FOO.COM", "root/joe@FOO.COM");
   }
 
+  @Test
+  public void testParsing() throws Exception {
+    final String principalNameFull = "HTTP/abc.com@EXAMPLE.COM";
+    final String principalNameWoRealm = "HTTP/abc.com";
+    final String principalNameWoHost = "HTTP@EXAMPLE.COM";
+
+    final KerberosName kerbNameFull = new KerberosName(principalNameFull);
+    Assert.assertEquals("HTTP", kerbNameFull.getServiceName());
+    Assert.assertEquals("abc.com", kerbNameFull.getHostName());
+    Assert.assertEquals("EXAMPLE.COM", kerbNameFull.getRealm());
+
+    final KerberosName kerbNamewoRealm = new KerberosName(principalNameWoRealm);
+    Assert.assertEquals("HTTP", kerbNamewoRealm.getServiceName());
+    Assert.assertEquals("abc.com", kerbNamewoRealm.getHostName());
+    Assert.assertEquals(null, kerbNamewoRealm.getRealm());
+
+    final KerberosName kerbNameWoHost = new KerberosName(principalNameWoHost);
+    Assert.assertEquals("HTTP", kerbNameWoHost.getServiceName());
+    Assert.assertEquals(null, kerbNameWoHost.getHostName());
+    Assert.assertEquals("EXAMPLE.COM", kerbNameWoHost.getRealm());
+  }
+
   @Test
   public void testToLowerCase() throws Exception {
     String rules =

+ 4 - 0
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/token/delegation/web/TestWebDelegationToken.java

@@ -31,6 +31,8 @@ import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHand
 import org.apache.hadoop.security.authentication.util.KerberosUtil;
 import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
 import org.codehaus.jackson.map.ObjectMapper;
+import org.apache.hadoop.test.GenericTestUtils;
+import org.apache.log4j.Level;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -198,6 +200,8 @@ public class TestWebDelegationToken {
     UserGroupInformation.setConfiguration(conf);
 
     jetty = createJettyServer();
+    GenericTestUtils.setLogLevel(KerberosAuthenticationHandler.LOG,
+        Level.TRACE);
   }
 
   @After