Could not find KafkaClient entry in the JAAS configuration
最近项目,需要Kafka基于GSSAPI认证模式,进行安全认证。然后通过Kafka官网文档等资料,完成认证操作。但是一个比较诡异的事是,代码在本地环境上,能够成功运行,但是基于Docker进行部署时,出现如下异常。后续,通过排查,发现Docker容器内,该文件存在,拥有对应的操作权限,且配置内容也是正确的。无奈之下,通读一遍JaasContext.defaultContext方法。发现该异常信息,
最近项目,需要Kafka基于GSSAPI认证模式,进行安全认证。然后通过Kafka官网文档等资料,完成认证操作。
但是一个比较诡异的事是,代码在本地环境上,能够成功运行,但是基于Docker进行部署时,出现如下异常。
后续,通过排查,发现Docker容器内,该文件存在,拥有对应的操作权限,且配置内容也是正确的。
无奈之下,通读一遍JaasContext.defaultContext方法。发现该异常信息,来源于configEntities属性判断处。
最后发现,configEntities属性,通过
jaasConfig.getAppConfigurationEntry(globalContextName)
获取,而globalContextName对应于KafkaClient字符串常量。
进入到该方法
到目前为止,基本上知道了configEntities局部变量,最终通过ConfigFile类的spi属性获取。而spi属性获取方式,是通过其内部的configuration属性获取到的。
到这里,想必各位比较好奇,ConfigFile中spi属性中configuration属性,究竟存储的是什么属性呢?
下面,让我们通过如下代码,来查看configuration属性值。
Configuration jaasConfig = Configuration.getConfiguration();
for (Field field : jaasConfig.getClass().getDeclaredFields()) {
if ("spi".equals(field.getName())) {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true); // Field 的 modifiers 是私有的
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setAccessible(true);
Object spi = field.get(jaasConfig);
for (Field spiField : spi.getClass().getDeclaredFields()) {
if ("configuration".equals(spiField.getName())) {
spiField.setAccessible(true);
return JSONObject.toJSONString(spiField.get(spi));
}
}
}
}
在创建消费者之前,运行这段代码,发现结果竟然是空的。
想必各位一定好奇,明明文件是存在的,为什么没有把文件内容给读取出来呢?无奈之下,通过idea远程连接Docker环境,查看其内部运行过程。结果大吃一惊,这种操作方式,configuration属性又有值了。
认证观察一下代码后,发现,spi属性,是在ConfigFile构造方法处,进行的初始化。而configuration属性加载,也是在Spi的构造方法,通过init方法,完成的初始化。
而代码处用于设置java.security.auth.login.config环境变量的代码,却在创建消费者处,进行的初始化。
也就是说,ConfigFile完成java.security.auth.login.config属性,加载文件内容之后,代码侧,才开始设置java.security.auth.login.config属性。
这也就解释了,为什么通过反射获取configuration属性值,会为空。
既然,原因找到了,那么怎么解决问题呢?
其实看到这里,这个异常的解决方法,很简单,在环境启动前,设置java.security.auth.login.config属性。
到此,整个异常解决。
更多推荐
所有评论(0)