Kerberos 认证 javax.security.auth.logon.LoginException:拒绝链接 (Connection refused)

文章讲述了项目中Hive和HDFS使用Kerberos进行权限认证时遇到的问题,服务重启后出现认证失败,分析了可能的原因,如配置文件失效和特定JDK版本的影响,强调了Kerberos异常信息的不足和排查难度。

kerberos 服务重启之后异常

项目中用到了hive 和hdfs ,权限认证使用了Kerberos,因为机房异常,导致了Kerberos 服务重启,结果发现本来运行正常的应用服务hive 和hdfs 认证失败,报错信息是

请添加图片描述
典型的网络连接异常

排查思路

验证Kerberos 服务

首先想到Kerberos服务异常,防火墙拦截。通过hdfs 命令发现 Kerberos 服务正常。
后边自己写了一个hive 链接测试应用,发现同一台机器上可以正常验证通过访问hive。

排查为什么拒绝链接

应用本身上线有一段时间,期间未发生这种报错,所以思路集中在配置文件,服务器hosts配置方向,后边通过自己的测试服务 正常链接排除的环境因素那么就是程序本身问题,奇怪的点事本身服务运行正常,突然报异常了。

这个就有点奇怪,之后对比了代码发现

Kerberos 配置写法导致

正确的写法

   try {
            Class.forName(JDBC_DRIVER);
 

            //登录Kerberos账号
            String keytabPath = "/opt/data/kerberos/" + keytab;

            Configuration configuration = new Configuration();
            configuration.set("hadoop.security.authentication", "Kerberos");
            configuration.set("java.security.krb5.conf", "/opt/data/kerberos/krb5.conf");
            UserGroupInformation.setConfiguration(configuration);

            UserGroupInformation.loginUserFromKeytab(krbUser, keytabPath);
            System.out.println("Kerberos 验证通过");

            Connection connection = null;
            ResultSet rs = null;
            PreparedStatement ps = null;
            try {
                connection = DriverManager.getConnection(CONNECTION_URL);
                ps = connection.prepareStatement("select * from ods_inc.k02_city");
                rs = ps.executeQuery();
                while (rs.next()) {
                    System.out.println(rs.getString(1));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
            return "exception";
        }
        return "finish";

    }

产生异常的写法

try {
            log.debug(keyTabPath);
            log.debug(confPath);
            //设置krb配置文件路径,注意一定要放在Configuration前面,不然不生效
            System.setProperty("java.security.krb5.conf", confPath);
            Configuration conf = new Configuration();
            //设置认证模式Kerberos
            conf.set("hadoop.security.authentication", "Kerberos");
            UserGroupInformation.setConfiguration(conf);
            //设置认证用户和krb认证文件路径
            UserGroupInformation.loginUserFromKeytab(krbUser, keyTabPath);
            log.info("Kerberos 验证成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Kerberos 验证失败", e);
            throw new PluginException("Kerberos 验证失败", e);
        }

关键点是
System.setProperty(“java.security.krb5.conf”, confPath);
这个配置文件在Kerberos 服务重启之后不生效了。

至于为什么不生效,欢迎高手一起研究交流。

总结

Kerberos 服务认证 内嵌在jdk中,某些jdk版本会导致Kerberos 认证异常,Kerberos 认证抛出的异常信息不足,很多时候排查问题比较耗费时间甄别,这种突然爆出的异常 应该和程序初始化有关系,或者Kerberos 服务重启之后的某些因素影响。

问题比较罕见,如果应用服务中环境可以通过防火墙策略配置,不建议使用Kerberos 认真大数据组件。

<think>嗯,用户遇到了Eclipse连接虚拟机时出现的javax.security.auth.login.LoginException错误,具体是找不到com.sun.security.auth.module.NTLoginModule这个LoginModule类。首先,我需要回忆一下JAAS的机制。JAAS通过配置文件指定LoginModule,如果配置不正确或者缺少对应的模块,就会抛出这类异常。用户可能是在Windows环境下尝试使用NTLoginModule,但虚拟机环境可能不支持,或者相关模块没有被正确加载。 查看用户提供的引用,特别是引用[1]中的情况,类似的错误是因为找不到LinuxLoginModule,而这里则是NTLoginModule。这可能涉及到不同操作系统的差异。NTLoginModule通常用于Windows的NT系统认证,而如果连接的是Linux虚拟机,可能需要替换为其他模块,比如LinuxLoginModule或者Krb5LoginModule,特别是如果涉及Kerberos认证的话。 接下来,用户提供的引用[4]提到了设置JVM的安全策略选项,可能需要检查Eclipse的JVM参数是否正确指向了策略文件。此外,引用[3]提到了RefreshFailedException的解决方法,可能涉及到凭证刷新问题,但当前问题更可能是配置错误导致的模块找不到。 可能的解决步骤包括:首先确认虚拟机环境是否需要特定的LoginModule,比如检查是否在Linux上错误配置了Windows的NTLoginModule。然后检查JAAS配置文件是否正确,是否指定了正确的模块。如果用户的环境是跨平台的,可能需要更换LoginModule类型。此外,确保相关的JAR文件(如ntloginmodule所在的jar)在类路径中,或者JRE的lib/ext目录下有对应的模块。如果问题依然存在,可能需要调整Eclipse的JVM参数,添加安全策略文件,或者更新安全配置。 另外,用户可能在连接Hadoop集群或其他需要安全认证的系统,这时候需要确认Kerberos配置是否正确,以及相关的登录模块是否被正确加载。例如,引用[2]中的代码示例展示了使用JAAS进行登录,如果配置名称"Sample"对应的LoginModule没有正确设置,就会出现类似错误。因此,检查JAAS配置文件中的条目是否匹配代码中的配置名称也很重要。 总结下来,解决步骤可能包括:检查JAAS配置,确认LoginModule类路径,调整JVM安全策略,更换适合操作系统的LoginModule,以及确保所有必要的安全模块已正确安装和配置。同时,参考已有的解决方案,如引用[3]和[4]中的方法,可能对用户有帮助。</think>针对Eclipse连接虚拟机时出现的$javax.security.auth.login.LoginException$错误"未找到$com.sun.security.auth.module.NTLoginModule$"问题,以下是分步解决方案: ### 1. 理解错误根源 该错误表明JVM在安全认证过程中无法找到指定的登录模块$NTLoginModule$,通常发生在: - JAAS配置文件未正确指定登录模块[^2] - JRE缺少对应操作系统的认证模块(如Windows模块用于Linux环境) - 安全策略文件未正确加载[^4] ### 2. 具体解决步骤 #### 步骤一:检查操作系统兼容性 $NTLoginModule$专用于**Windows NT系统认证**,若连接的是Linux虚拟机: ```java // 错误配置示例 LoginModule com.sun.security.auth.module.NTLoginModule required; ``` 应替换为Linux认证模块: ```java // 正确配置示例 LoginModule com.sun.security.auth.module.LinuxLoginModule required; ``` #### 步骤二:验证JAAS配置文件 创建/修改JAAS配置文件(如$jaas.conf$): ``` Sample { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="/path/to/keytab"; }; ``` 在Eclipse的JVM参数中添加: ``` -Djava.security.auth.login.config=/path/to/jaas.conf ``` #### 步骤三:检查模块加载路径 确认JRE扩展目录包含$ntloginmodule$: ``` ${JAVA_HOME}/jre/lib/ext/sunpkcs11.jar ``` 若缺失该JAR文件,需重新安装对应版本的JRE/JDK。 #### 步骤四:调整安全策略(关键步骤) 参考Hadoop安全策略配置,在Eclipse的`eclipse.ini`中添加: ``` -Djava.security.policy=file:///path/to/plugin-security.policy -Djava.security.auth.policy=file:///path/to/jaas.policy ``` ### 3. 验证配置 通过测试代码验证JAAS配置: ```java public class AuthTest { public static void main(String[] args) { System.setProperty("java.security.auth.login.config", "jaas.conf"); try { LoginContext lc = new LoginContext("Sample"); lc.login(); System.out.println("Authentication Success!"); } catch (LoginException e) { e.printStackTrace(); } } } ``` ### 4. 特殊场景处理 若使用Kerberos认证,需额外配置: ```properties # krb5.conf [libdefaults] default_realm = YOURDOMAIN.COM ``` 并在JVM参数添加: ``` -Djavax.security.auth.useSubjectCredsOnly=false ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值