HADOOP-13890. Maintain HTTP/host as SPNEGO SPN support and fix KerberosName parsing. Contributed by Xiaoyu Yao.
This commit is contained in:
parent
6ba9587d37
commit
f5e0bd30fd
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue