HADOOP-9446. Support Kerberos SPNEGO for IBM JDK. (Yu Gao via llu)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1513688 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5a33cdabd8
commit
8a7cec29fe
|
@ -37,6 +37,8 @@ import java.security.PrivilegedExceptionAction;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
|
||||
|
||||
/**
|
||||
* The {@link KerberosAuthenticator} implements the Kerberos SPNEGO authentication sequence.
|
||||
* <p/>
|
||||
|
@ -75,13 +77,29 @@ public class KerberosAuthenticator implements Authenticator {
|
|||
|
||||
private static final String OS_LOGIN_MODULE_NAME;
|
||||
private static final boolean windows = System.getProperty("os.name").startsWith("Windows");
|
||||
private static final boolean is64Bit = System.getProperty("os.arch").contains("64");
|
||||
private static final boolean aix = System.getProperty("os.name").equals("AIX");
|
||||
|
||||
/* Return the OS login module class name */
|
||||
private static String getOSLoginModuleName() {
|
||||
if (IBM_JAVA) {
|
||||
if (windows) {
|
||||
return is64Bit ? "com.ibm.security.auth.module.Win64LoginModule"
|
||||
: "com.ibm.security.auth.module.NTLoginModule";
|
||||
} else if (aix) {
|
||||
return is64Bit ? "com.ibm.security.auth.module.AIX64LoginModule"
|
||||
: "com.ibm.security.auth.module.AIXLoginModule";
|
||||
} else {
|
||||
return "com.ibm.security.auth.module.LinuxLoginModule";
|
||||
}
|
||||
} else {
|
||||
return windows ? "com.sun.security.auth.module.NTLoginModule"
|
||||
: "com.sun.security.auth.module.UnixLoginModule";
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
if (windows) {
|
||||
OS_LOGIN_MODULE_NAME = "com.sun.security.auth.module.NTLoginModule";
|
||||
} else {
|
||||
OS_LOGIN_MODULE_NAME = "com.sun.security.auth.module.UnixLoginModule";
|
||||
}
|
||||
OS_LOGIN_MODULE_NAME = getOSLoginModuleName();
|
||||
}
|
||||
|
||||
private static final AppConfigurationEntry OS_SPECIFIC_LOGIN =
|
||||
|
@ -92,13 +110,22 @@ public class KerberosAuthenticator implements Authenticator {
|
|||
private static final Map<String, String> USER_KERBEROS_OPTIONS = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
USER_KERBEROS_OPTIONS.put("doNotPrompt", "true");
|
||||
USER_KERBEROS_OPTIONS.put("useTicketCache", "true");
|
||||
USER_KERBEROS_OPTIONS.put("renewTGT", "true");
|
||||
String ticketCache = System.getenv("KRB5CCNAME");
|
||||
if (ticketCache != null) {
|
||||
USER_KERBEROS_OPTIONS.put("ticketCache", ticketCache);
|
||||
if (IBM_JAVA) {
|
||||
USER_KERBEROS_OPTIONS.put("useDefaultCcache", "true");
|
||||
} else {
|
||||
USER_KERBEROS_OPTIONS.put("doNotPrompt", "true");
|
||||
USER_KERBEROS_OPTIONS.put("useTicketCache", "true");
|
||||
}
|
||||
if (ticketCache != null) {
|
||||
if (IBM_JAVA) {
|
||||
// The first value searched when "useDefaultCcache" is used.
|
||||
System.setProperty("KRB5CCNAME", ticketCache);
|
||||
} else {
|
||||
USER_KERBEROS_OPTIONS.put("ticketCache", ticketCache);
|
||||
}
|
||||
}
|
||||
USER_KERBEROS_OPTIONS.put("renewTGT", "true");
|
||||
}
|
||||
|
||||
private static final AppConfigurationEntry USER_KERBEROS_LOGIN =
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.hadoop.security.authentication.util.KerberosUtil;
|
|||
import org.ietf.jgss.GSSContext;
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.Oid;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -44,6 +45,8 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
|
||||
|
||||
/**
|
||||
* The {@link KerberosAuthenticationHandler} implements the Kerberos SPNEGO authentication mechanism for HTTP.
|
||||
* <p/>
|
||||
|
@ -77,18 +80,33 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
|
|||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, String> options = new HashMap<String, String>();
|
||||
options.put("keyTab", keytab);
|
||||
options.put("principal", principal);
|
||||
options.put("useKeyTab", "true");
|
||||
options.put("storeKey", "true");
|
||||
options.put("doNotPrompt", "true");
|
||||
options.put("useTicketCache", "true");
|
||||
options.put("renewTGT", "true");
|
||||
if (IBM_JAVA) {
|
||||
options.put("useKeytab",
|
||||
keytab.startsWith("file://") ? keytab : "file://" + keytab);
|
||||
options.put("principal", principal);
|
||||
options.put("credsType", "acceptor");
|
||||
} else {
|
||||
options.put("keyTab", keytab);
|
||||
options.put("principal", principal);
|
||||
options.put("useKeyTab", "true");
|
||||
options.put("storeKey", "true");
|
||||
options.put("doNotPrompt", "true");
|
||||
options.put("useTicketCache", "true");
|
||||
options.put("renewTGT", "true");
|
||||
options.put("isInitiator", "false");
|
||||
}
|
||||
options.put("refreshKrb5Config", "true");
|
||||
options.put("isInitiator", "false");
|
||||
String ticketCache = System.getenv("KRB5CCNAME");
|
||||
if (ticketCache != null) {
|
||||
options.put("ticketCache", ticketCache);
|
||||
if (IBM_JAVA) {
|
||||
options.put("useDefaultCcache", "true");
|
||||
// The first value searched when "useDefaultCcache" is used.
|
||||
System.setProperty("KRB5CCNAME", ticketCache);
|
||||
options.put("renewTGT", "true");
|
||||
options.put("credsType", "both");
|
||||
} else {
|
||||
options.put("ticketCache", ticketCache);
|
||||
}
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
options.put("debug", "true");
|
||||
|
@ -294,8 +312,18 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
|
|||
public AuthenticationToken run() throws Exception {
|
||||
AuthenticationToken token = null;
|
||||
GSSContext gssContext = null;
|
||||
GSSCredential gssCreds = null;
|
||||
try {
|
||||
gssContext = gssManager.createContext((GSSCredential) null);
|
||||
if (IBM_JAVA) {
|
||||
// IBM JDK needs non-null credentials to be passed to createContext here, with
|
||||
// SPNEGO mechanism specified, otherwise JGSS will use its default mechanism
|
||||
// only, which is Kerberos V5.
|
||||
gssCreds = gssManager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME,
|
||||
new Oid[]{KerberosUtil.getOidInstance("GSS_SPNEGO_MECH_OID"),
|
||||
KerberosUtil.getOidInstance("GSS_KRB5_MECH_OID")},
|
||||
GSSCredential.ACCEPT_ONLY);
|
||||
}
|
||||
gssContext = gssManager.createContext(gssCreds);
|
||||
byte[] serverToken = gssContext.acceptSecContext(clientToken, 0, clientToken.length);
|
||||
if (serverToken != null && serverToken.length > 0) {
|
||||
String authenticate = base64.encodeToString(serverToken);
|
||||
|
@ -317,6 +345,9 @@ public class KerberosAuthenticationHandler implements AuthenticationHandler {
|
|||
if (gssContext != null) {
|
||||
gssContext.dispose();
|
||||
}
|
||||
if (gssCreds != null) {
|
||||
gssCreds.dispose();
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.util.Locale;
|
|||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.Oid;
|
||||
|
||||
import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
|
||||
|
||||
public class KerberosUtil {
|
||||
|
||||
/* Return the Kerberos login module name */
|
||||
|
@ -40,7 +42,11 @@ public class KerberosUtil {
|
|||
throws ClassNotFoundException, GSSException, NoSuchFieldException,
|
||||
IllegalAccessException {
|
||||
Class<?> oidClass;
|
||||
if (System.getProperty("java.vendor").contains("IBM")) {
|
||||
if (IBM_JAVA) {
|
||||
if ("NT_GSS_KRB5_PRINCIPAL".equals(oidName)) {
|
||||
// IBM JDK GSSUtil class does not have field for krb5 principal oid
|
||||
return new Oid("1.2.840.113554.1.2.2.1");
|
||||
}
|
||||
oidClass = Class.forName("com.ibm.security.jgss.GSSUtil");
|
||||
} else {
|
||||
oidClass = Class.forName("sun.security.jgss.GSSUtil");
|
||||
|
|
|
@ -22,31 +22,33 @@ import org.apache.hadoop.classification.InterfaceAudience;
|
|||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
|
||||
/**
|
||||
* A helper class for getting build-info of the java-vm.
|
||||
*
|
||||
* A helper class for getting build-info of the java-vm.
|
||||
*
|
||||
*/
|
||||
@InterfaceAudience.LimitedPrivate({"HBase"})
|
||||
@InterfaceStability.Unstable
|
||||
public class PlatformName {
|
||||
/**
|
||||
* The complete platform 'name' to identify the platform as
|
||||
* The complete platform 'name' to identify the platform as
|
||||
* per the java-vm.
|
||||
*/
|
||||
private static final String PLATFORM_NAME = System.getProperty("os.name") + "-" +
|
||||
System.getProperty("os.arch") + "-" +
|
||||
System.getProperty("sun.arch.data.model");
|
||||
|
||||
public static final String PLATFORM_NAME =
|
||||
(System.getProperty("os.name").startsWith("Windows")
|
||||
? System.getenv("os") : System.getProperty("os.name"))
|
||||
+ "-" + System.getProperty("os.arch")
|
||||
+ "-" + System.getProperty("sun.arch.data.model");
|
||||
|
||||
/**
|
||||
* The java vendor name used in this platform.
|
||||
* The java vendor name used in this platform.
|
||||
*/
|
||||
public static final String JAVA_VENDOR_NAME = System.getProperty("java.vendor");
|
||||
|
||||
/**
|
||||
* A public static variable to indicate the current java vendor is
|
||||
* IBM java or not.
|
||||
* A public static variable to indicate the current java vendor is
|
||||
* IBM java or not.
|
||||
*/
|
||||
public static final boolean IBM_JAVA = JAVA_VENDOR_NAME.contains("IBM");
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(PLATFORM_NAME);
|
||||
}
|
|
@ -52,6 +52,8 @@ Release 2.1.1-beta - UNRELEASED
|
|||
|
||||
IMPROVEMENTS
|
||||
|
||||
HADOOP-9446. Support Kerberos SPNEGO for IBM JDK. (Yu Gao via llu)
|
||||
|
||||
HADOOP-9787. ShutdownHelper util to shutdown threads and threadpools.
|
||||
(Karthik Kambatla via Sandy Ryza)
|
||||
|
||||
|
|
|
@ -427,7 +427,6 @@ public class UserGroupInformation {
|
|||
} else {
|
||||
USER_KERBEROS_OPTIONS.put("doNotPrompt", "true");
|
||||
USER_KERBEROS_OPTIONS.put("useTicketCache", "true");
|
||||
USER_KERBEROS_OPTIONS.put("renewTGT", "true");
|
||||
}
|
||||
String ticketCache = System.getenv("KRB5CCNAME");
|
||||
if (ticketCache != null) {
|
||||
|
@ -438,6 +437,7 @@ public class UserGroupInformation {
|
|||
USER_KERBEROS_OPTIONS.put("ticketCache", ticketCache);
|
||||
}
|
||||
}
|
||||
USER_KERBEROS_OPTIONS.put("renewTGT", "true");
|
||||
USER_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS);
|
||||
}
|
||||
private static final AppConfigurationEntry USER_KERBEROS_LOGIN =
|
||||
|
@ -453,8 +453,8 @@ public class UserGroupInformation {
|
|||
KEYTAB_KERBEROS_OPTIONS.put("doNotPrompt", "true");
|
||||
KEYTAB_KERBEROS_OPTIONS.put("useKeyTab", "true");
|
||||
KEYTAB_KERBEROS_OPTIONS.put("storeKey", "true");
|
||||
KEYTAB_KERBEROS_OPTIONS.put("refreshKrb5Config", "true");
|
||||
}
|
||||
KEYTAB_KERBEROS_OPTIONS.put("refreshKrb5Config", "true");
|
||||
KEYTAB_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS);
|
||||
}
|
||||
private static final AppConfigurationEntry KEYTAB_KERBEROS_LOGIN =
|
||||
|
@ -615,11 +615,17 @@ public class UserGroupInformation {
|
|||
}
|
||||
try {
|
||||
Map<String,String> krbOptions = new HashMap<String,String>();
|
||||
krbOptions.put("doNotPrompt", "true");
|
||||
krbOptions.put("useTicketCache", "true");
|
||||
krbOptions.put("useKeyTab", "false");
|
||||
if (IBM_JAVA) {
|
||||
krbOptions.put("useDefaultCcache", "true");
|
||||
// The first value searched when "useDefaultCcache" is used.
|
||||
System.setProperty("KRB5CCNAME", ticketCache);
|
||||
} else {
|
||||
krbOptions.put("doNotPrompt", "true");
|
||||
krbOptions.put("useTicketCache", "true");
|
||||
krbOptions.put("useKeyTab", "false");
|
||||
krbOptions.put("ticketCache", ticketCache);
|
||||
}
|
||||
krbOptions.put("renewTGT", "false");
|
||||
krbOptions.put("ticketCache", ticketCache);
|
||||
krbOptions.putAll(HadoopConfiguration.BASIC_JAAS_OPTIONS);
|
||||
AppConfigurationEntry ace = new AppConfigurationEntry(
|
||||
KerberosUtil.getKrb5LoginModuleName(),
|
||||
|
|
Loading…
Reference in New Issue