diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java index c6d188170c..f51bbd68f7 100644 --- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java +++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/KerberosAuthenticationHandler.java @@ -18,6 +18,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.hadoop.security.authentication.util.KerberosName; import org.apache.hadoop.security.authentication.util.KerberosUtil; +import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSManager; @@ -48,25 +49,32 @@ import java.util.Set; import java.util.regex.Pattern; +import com.google.common.collect.HashMultimap; + import static org.apache.hadoop.util.PlatformName.IBM_JAVA; /** - * The {@link KerberosAuthenticationHandler} implements the Kerberos SPNEGO authentication mechanism for HTTP. + * The {@link KerberosAuthenticationHandler} implements the Kerberos SPNEGO + * authentication mechanism for HTTP. *
* The supported configuration properties are: *
HTTP/${HOSTNAME}@{REALM}
. The realm can be omitted from the
- * principal as the JDK GSS libraries will use the realm name of the configured default realm.
+ * HTTP/${HOSTNAME}@{REALM}
. The realm can be omitted from the
+ * principal as the JDK GSS libraries will use the realm name of the configured
+ * default realm.
* It does not have a default value.- * It creates a Kerberos context using the principal and keytab specified in the configuration. + * It creates a Kerberos context using the principal and keytab specified in + * the configuration. *
* This method is invoked by the {@link AuthenticationFilter#init} method.
*
@@ -225,15 +272,27 @@ public void init(Properties config) throws ServletException {
throw new AuthenticationException(le);
}
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(),
+ spnegoPrincipal);
+ serverPrincipalMap.put(kerbName.getHostName(), spnegoPrincipal);
+ } else {
+ LOG.warn("HTTP principal: {} is invalid for SPNEGO!",
+ spnegoPrincipal);
+ }
}
try {
- gssManager = Subject.doAs(serverSubject, new PrivilegedExceptionActionnull
if it is in progress (in this case the handler handles the response to the client).
+ * @return an authentication token if the Kerberos SPNEGO sequence is complete
+ * and valid, null
if it is in progress (in this case the handler
+ * handles the response to the client).
*
* @throws IOException thrown if an IO error occurred.
* @throws AuthenticationException thrown if Kerberos SPNEGO sequence failed.
*/
@Override
- public AuthenticationToken authenticate(HttpServletRequest request, final HttpServletResponse response)
- throws IOException, AuthenticationException {
+ public AuthenticationToken authenticate(HttpServletRequest request,
+ final HttpServletResponse response)
+ throws IOException, AuthenticationException {
AuthenticationToken token = null;
- String authorization = request.getHeader(KerberosAuthenticator.AUTHORIZATION);
+ String authorization = request.getHeader(
+ KerberosAuthenticator.AUTHORIZATION);
- if (authorization == null || !authorization.startsWith(KerberosAuthenticator.NEGOTIATE)) {
+ if (authorization == null
+ || !authorization.startsWith(KerberosAuthenticator.NEGOTIATE)) {
response.setHeader(WWW_AUTHENTICATE, KerberosAuthenticator.NEGOTIATE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
if (authorization == null) {
- LOG.trace("SPNEGO starting");
+ LOG.trace("SPNEGO starting for url: {}", request.getRequestURL());
} else {
- LOG.warn("'" + KerberosAuthenticator.AUTHORIZATION + "' does not start with '" +
+ LOG.warn("'" + KerberosAuthenticator.AUTHORIZATION +
+ "' does not start with '" +
KerberosAuthenticator.NEGOTIATE + "' : {}", authorization);
}
} else {
- authorization = authorization.substring(KerberosAuthenticator.NEGOTIATE.length()).trim();
+ authorization = authorization.substring(
+ KerberosAuthenticator.NEGOTIATE.length()).trim();
final Base64 base64 = new Base64(0);
final byte[] clientToken = base64.decode(authorization);
final String serverName = InetAddress.getByName(request.getServerName())
.getCanonicalHostName();
try {
- token = Subject.doAs(serverSubject, new PrivilegedExceptionAction