網上找了一下,自己寫了個KerberosUtil工具類,測試過可以用。
注意這個不是 org.apache.hadoop.security.authentication.util.KerberosUtil類。
public class KerberosUtil { /** * 通過Kerberos認證用戶的,注意keytabPath為本地路徑不是HDFS路徑 * @param conf * @param user user為運行jar的hadoop用戶 * @param keytabPath * @throws IOException */ public static void AuthenByKerberos(Configuration conf,String user,String keytabPath) throws IOException{ UserGroupInformation.setConfiguration(conf); if(! UserGroupInformation.isSecurityEnabled()) return; UserGroupInformation.getCurrentUser().setAuthenticationMethod(AuthenticationMethod.KERBEROS); UserGroupInformation.loginUserFromKeytab(user,keytabPath); } /** * 通過Kerberos認證用戶的,注意keytabPath為本地路徑不是HDFS路徑 * @param conf * @param keytabPath * @throws IOException */ public static void AuthenByKerberos(Configuration conf,String keytabPath) throws IOException{ String user=UserGroupInformation.getLoginUser().getUserName(); AuthenByKerberos(conf,user,keytabPath); } }
其實網上用的SecurityUtil.login()登錄驗證,源碼中也是調用 UserGroupInformation.loginUserFromKeytab(),只不過多做了一些處理。
下面是login()方法的源碼。
/** * Login as a principal specified in config. Substitute $host in user's Kerberos principal * name with hostname. If non-secure mode - return. If no keytab available - * bail out with an exception * * @param conf * conf to use * @param keytabFileKey * the key to look for keytab file in conf * @param userNameKey * the key to look for user's Kerberos principal name in conf * @param hostname * hostname to use for substitution * @throws IOException if the config doesn't specify a keytab */ @InterfaceAudience.Public @InterfaceStability.Evolving public static void login(final Configuration conf, final String keytabFileKey, final String userNameKey, String hostname) throws IOException { if(! UserGroupInformation.isSecurityEnabled()) return; String keytabFilename = conf.get(keytabFileKey); if (keytabFilename == null || keytabFilename.length() == 0) { throw new IOException("Running in secure mode, but config doesn't have a keytab"); } String principalConfig = conf.get(userNameKey, System .getProperty("user.name")); String principalName = SecurityUtil.getServerPrincipal(principalConfig, hostname); UserGroupInformation.loginUserFromKeytab(principalName, keytabFilename); }
另:在linux 的shell窗口做認證命令kinit -kt /home/..../cluster_keytab/fileName.keytab userName (寫自己的認證文件和用戶名)