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

kerberos 服务重启之后异常

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

典型的网络连接异常

排查思路

验证Kerberos 服务

首先想到Kerberos服务异常,防火墙拦截。通过hdfs 命令发现 Kerberos 服务正常。

后边自己写了一个hive 链接测试应用,发现同一台机器上可以正常验证通过访问hive。

排查为什么拒绝链接

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

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

Kerberos 配置写法导致

正确的写法

java 复制代码
   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";

    }

产生异常的写法

java 复制代码
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 认真大数据组件。

相关推荐
皮皮林5512 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河2 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程5 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅6 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者7 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺7 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart9 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP10 小时前
MyBatis-mybatis入门与增删改查
java
孟陬13 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端