Can't get Kerberos realm

本文分析了在Java环境中遇到的无法获取Kerberos Realm的问题,详细探讨了问题出现的原因,包括加载krb5.conf文件时发生的FileNotFoundException。同时,针对com.google.common.util.concurrent.UncheckedTimeoutException: java.util.concurrent.TimeoutException的错误,解释了可能的成因,并提出了通过设置JVM启动参数来解决这两个问题的方法。
摘要由CSDN通过智能技术生成

1. Can't get Kerberos realm

原因分析

原始代码为:

org.apache.hadoop.security.UserGroupInformation.setConfiguration(conf) 
sun.security.krb5.Config.refresh()

  

首先根据传进来的Hadoop配置conf,去设置UserGroupInformation(UGI),方法的调用关系如下(删除了部分不相关代码):

public static void setConfiguration(Configuration conf) {
  initialize(conf, true);
}

initialize方法如下 

private static synchronized void initialize(Configuration conf, boolean overrideNameRules) {
  authenticationMethod = SecurityUtil.getAuthenticationMethod(conf);
  if (overrideNameRules || !HadoopKerberosName.hasRulesBeenSet()) {
    try {
      HadoopKerberosName.setConfiguration(conf);
    } catch (IOException ioe) {
      throw new RuntimeException(
          "Problem with Kerberos auth_to_local name configuration", ioe);
    }
  }
  ......
}

  

setConfiguration方法如下

public static void setConfiguration(Configuration conf) throws IOException {
  final String defaultRule;
  switch (SecurityUtil.getAuthenticationMethod(conf)) {
    case KERBEROS:
    case KERBEROS_SSL:
      try {
        KerberosUtil.getDefaultRealm();
      } catch (Exception ke) {
        throw new IllegalArgumentException("Can't get Kerberos realm", ke);
      }
      ......
  }
  ......
}

  

getDefaultRealm使用了反射,目的是为了兼容两套jdk,即IBM(com.ibm.security.krb5.internal.Config) 和 Oracle(sun.security.krb5.Config)

public static String getDefaultRealm() 
    throws ClassNotFoundException, NoSuchMethodException, 
    IllegalArgumentException, IllegalAccessException, 
    InvocationTargetException {
  Object kerbConf;
  Class<?> classRef;
  Method getInstanceMethod;
  Method getDefaultRealmMethod;
  if (System.getProperty("java.vendor").contains("IBM")) {
    classRef = Class.forName("com.ibm.security.krb5.internal.Config"); // 获取IBM jdk的类引用
  } else {
    classRef = Class.forName("sun.security.krb5.Config"); // 获取Oracle jdk的类引用
  }
  getInstanceMethod = classRef.getMethod("getInstance", new Class[0]);
  kerbConf = getInstanceMethod.invoke(classRef, new Object[0]);
  getDefaultRealmMethod = classRef.getDeclaredMethod("getDefaultRealm", new Class[0]);
  return (String)getDefaultRealmMethod.invoke(kerbConf, new Object[0]);
}

  

从上述代码来看,先获取Config类引用,然后getInstanceMethod是获得getInstance方法,再次getDefaultRealmMethod是获得getDefaultRealm方法。

因此,假设我们是使用的Oracle的JDK,那么最后是调用的sun.security.krb5.getDefaultRealm()。接下来看一下sun.security.krb5.getDefaultRealm()是如何实现的。

public String getDefaultRealm() throws KrbException {
  if(this.defaultRealm != null) { // 如果defaultRealm不为空,直接返回defaultRealm
    return this.defa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值