diff --git a/src/com/fr/plugin/hdfs/repository/core/HDFSRepositoryFactory.java b/src/com/fr/plugin/hdfs/repository/core/HDFSRepositoryFactory.java index e350a49..9acfe21 100644 --- a/src/com/fr/plugin/hdfs/repository/core/HDFSRepositoryFactory.java +++ b/src/com/fr/plugin/hdfs/repository/core/HDFSRepositoryFactory.java @@ -89,18 +89,19 @@ public class HDFSRepositoryFactory extends ConfigRepositoryFactory { System.setProperty("java.security.krb5.conf", krb5Conf); conf.set("hadoop.security.authentication", "kerberos"); + processConfForPrincipal(conf, principal); //类似OSGI下,类加载需要设置SecurityUtil.setSecurityInfoProviders(new AnnotatedSecurityInfo()); //refer to https://stackoverflow.com/questions/37608049/how-to-connect-with-hdfs-via-kerberos-from-osgi-bundles SecurityUtil.setSecurityInfoProviders(new AnnotatedSecurityInfo()); //UserGroupInformation初始化 UserGroupInformation.setConfiguration(conf); - UserGroupInformation.loginUserFromKeytab(config.getPrincipal(), config.getKeyTab()); + UserGroupInformation.loginUserFromKeytab(principal, config.getKeyTab()); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } finally { kerberosAuthModeSet = true; } - } else if (kerberosAuthModeSet){ + } else if (kerberosAuthModeSet) { conf.set("hadoop.security.authorization", "false"); conf.set("hadoop.security.authentication", "simple"); } @@ -144,4 +145,25 @@ public class HDFSRepositoryFactory extends ConfigRepositoryFactory { && StringUtils.isNotEmpty(config.getPrincipal()) && StringUtils.isNotEmpty(config.getKrbConf()); } + + + /** + * BI-third内置了hadoop2.6的包,插件优先从lib下加载类, + * 此时kerberos认证会报错"Failed to specify server's Kerberos principal name" + * 需要设置一下principal的格式 + * @param conf + * @param principal + */ + private void processConfForPrincipal(Configuration conf, String principal) { + //2.6.2以前的版本hdfs-site.xml没有默认的pricipal格式设置,需要手动加上 + //根据Kerberos V5 principal的格式primary/instance@REALM,确定实际的格式 + String principalPattern; + int primaryIdx = principal.indexOf("hdfs/"); + int atIdx = principal.indexOf("@"); + if (primaryIdx > -1 && atIdx > primaryIdx) { + String name = principal.substring(primaryIdx + "hdfs/".length(), atIdx - 1); + principalPattern = principal.replace(name, "*"); + conf.set("dfs.namenode.kerberos.principal.pattern", principalPattern); + } + } }