|
|
|
@ -107,18 +107,11 @@ public class HDFSRepositoryFactory extends ConfigRepositoryFactory<HDFSConfig> {
|
|
|
|
|
conf.set("hadoop.security.authentication", "kerberos"); |
|
|
|
|
|
|
|
|
|
//需要重新刷新一下让krb5.conf配置生效
|
|
|
|
|
refreshConfig(); |
|
|
|
|
reset(); |
|
|
|
|
|
|
|
|
|
//类似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()); |
|
|
|
|
|
|
|
|
|
//重置defaultRealm,hadoop2.7以前没有提供resetDefaultRealm方法,需要反射设置一下这个变量,否则无法登录
|
|
|
|
|
Field field = KerberosName.class.getDeclaredField("defaultRealm"); |
|
|
|
|
assert field != null; |
|
|
|
|
field.setAccessible(true); |
|
|
|
|
field.set(KerberosName.class, KerberosUtil.getDefaultRealm()); |
|
|
|
|
|
|
|
|
|
//UserGroupInformation初始化和登录验证
|
|
|
|
|
UserGroupInformation.setConfiguration(conf); |
|
|
|
|
UserGroupInformation.loginUserFromKeytab(principal, keyTab); |
|
|
|
@ -210,6 +203,10 @@ public class HDFSRepositoryFactory extends ConfigRepositoryFactory<HDFSConfig> {
|
|
|
|
|
&& StringUtils.isNotEmpty(config.getKrbConf()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void reset() throws Exception { |
|
|
|
|
refreshConfig(); |
|
|
|
|
resetDeFaultRealm(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -230,4 +227,28 @@ public class HDFSRepositoryFactory extends ConfigRepositoryFactory<HDFSConfig> {
|
|
|
|
|
Method refreshMethod = configClassRef.getDeclaredMethod("refresh"); |
|
|
|
|
refreshMethod.invoke(kerbConf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 重置defaultRealm, |
|
|
|
|
* hadoop2.7以前没有提供resetDefaultRealm方法, |
|
|
|
|
* 需要反射设置一下这个变量,否则无法登录 |
|
|
|
|
* <p> |
|
|
|
|
* KerberosName有个静态块设置defaultRealm为KerberosUtil.getDefaultRealm() |
|
|
|
|
* 如果Config对象重新通过System.setProperty设置过,这个时候需要重新设置一下, |
|
|
|
|
* 否则这个defaultRealm还是之前的,如果有其他的kerberos认证的client设置过krb5.conf文件, |
|
|
|
|
* 此时获取的defaultRealm是错误的或者为null,所以需要重置一下defaultRealm保证本次访问 |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* 同理如果其它地方使用Kerberos认证出现Login failed时也应该怀疑krb5文件没有刷新和KerberosName没有重置 |
|
|
|
|
* |
|
|
|
|
* @throws Exception |
|
|
|
|
*/ |
|
|
|
|
private void resetDeFaultRealm() throws Exception { |
|
|
|
|
|
|
|
|
|
Field field = KerberosName.class.getDeclaredField("defaultRealm"); |
|
|
|
|
assert field != null; |
|
|
|
|
field.setAccessible(true); |
|
|
|
|
field.set(KerberosName.class, KerberosUtil.getDefaultRealm()); |
|
|
|
|
} |
|
|
|
|
} |