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

This commit is contained in:
Xiaoyu Yao 2016-12-14 13:41:40 -08:00
parent 6ba9587d37
commit f5e0bd30fd
4 changed files with 38 additions and 11 deletions

View File

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

View File

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

View File

@ -82,6 +82,28 @@ public class TestKerberosName {
checkTranslation("root/joe@FOO.COM", "root/joe@FOO.COM"); 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 @Test
public void testToLowerCase() throws Exception { public void testToLowerCase() throws Exception {
String rules = String rules =

View File

@ -31,6 +31,8 @@ import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHa
import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler; import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler;
import org.apache.hadoop.security.authentication.util.KerberosUtil; import org.apache.hadoop.security.authentication.util.KerberosUtil;
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager; import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.log4j.Level;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
@ -197,6 +199,8 @@ public class TestWebDelegationToken {
UserGroupInformation.setConfiguration(conf); UserGroupInformation.setConfiguration(conf);
jetty = createJettyServer(); jetty = createJettyServer();
GenericTestUtils.setLogLevel(KerberosAuthenticationHandler.LOG,
Level.TRACE);
} }
@After @After