0


java通过Kerberos认证方式连接hive

在数据源管理功能中,需要适配mysql、postgresql、hive等数据源。mysql和postgresql连接方式一致,只需要驱动和jdbcurl即可,而hive背后是大数据集群,多采用Kerberos的方式保护集群环境,要想与大数据集群正常交互,需要经过kdc认证获取ticket,因此获取hive连接前需要先通过Kerberos认证

Java实现Kerberos认证

主要方法

# 从keytab文件中加载用户标识并登录
org.apache.hadoop.security.UserGroupInformation#loginUserFromKeytab

依赖

kerberos相关配置文件:krb5.conf、keytab文件从大数据集群管理员那获取
依赖:hive-jdbc:3.1.3(hive安装目录中带有该驱动包,可查看使用的版本)、hadoop-common:3.3.6,版本需和hive服务版本一致,在springboot3的框架下需要排除以下依赖,否则启动报错

<dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.jdbc.version}</version><exclusions><exclusion><artifactId>HikariCP-java7</artifactId><groupId>com.zaxxer</groupId></exclusion><exclusion><artifactId>javax.servlet.jsp</artifactId><groupId>org.glassfish.web</groupId></exclusion><exclusion><artifactId>jetty-runner</artifactId><groupId>org.eclipse.jetty</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version><exclusions><exclusion><artifactId>commons-lang3</artifactId><groupId>org.apache.commons</groupId></exclusion><exclusion><artifactId>curator-client</artifactId><groupId>org.apache.curator</groupId></exclusion></exclusions></dependency>

示例

String confPath ="\xxx\krb5.conf";String keytabPath ="\xxx\hive.service.keytab";String principal ="hive/xxx@xxx";System.setProperty("java.security.krb5.conf", confPath);//System.setProperty("sun.security.krb5.debug", "true");//System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");Configuration configuration =newConfiguration();
configuration.set("hadoop.security.authentication","KERBEROS");UserGroupInformation.setConfiguration(configuration);try{UserGroupInformation.loginUserFromKeytab(principal, keytabPath);}catch(IOException e){
    log.error("authKerberos exception", e);thrownewBizException("kerberos认证失败");}

除了上述方式外,也可采用JAAS可插拔的认证模块进行Kerberos认证

续期

Kerberos的ticket存在有效期,过期后导致服务不可用
Kerberos ticket存在两种有效期,ticket timelife(票据生命周期)、renewable lifetime(可再生周期)

  • ticket的时间超过ticket lifetime时,该ticket将不可用
  • 在renewable lifetime的时间内,可以对即将过期的ticket进行续期,超过renewable lifetime时间后,无法续期
  • 例如kerb5.conf文件中的配置:ticket_lifetime = 24h renewable_lifetime = 7d,则在登录后的24小时内,可以对即将过期的ticket进行续期,距第一次登录7天后,将不再允许续期

UserGroupInformation提供了认证续期的私有方法

UserGroupInformation#reloginFromKeytab(boolean)

,该方法有两个触发入口

UserGroupInformation#checkTGTAndReloginFromKeytab

UserGroupInformation#reloginFromKeytab()

在这里插入图片描述
在这里插入图片描述
值得注意的是

UserGroupInformation#loginUserFromKeytab

方法中会开启异步任务,定时触发续期方法,触发的续期方法即是

UserGroupInformation#reloginFromKeytab()

在这里插入图片描述
在这里插入图片描述
向线程池中提交续期的任务
在这里插入图片描述
在这里插入图片描述

也可以自定义触发续期的逻辑, 定期触发

UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab()

连接hive

Kerberos认证之后,使用hive-jdbc连接hive,之后与连接mysql、pg的方式无异,使用DriverManager或数据源连接池Hikari皆可

遇到的问题

一开始选择

hadoop-common

的版本是

3.1.3

,执行Kerberos认证时报错
在这里插入图片描述

KerberosUtil

无法访问

sun.security.krb5.Config

(它在

java.security.jgss

模块中)。

分析

本项目采用的框架是spring boot3版本,最低要求的jdk版本是17,而Java在9之后引入了模块化机制,模块必须显式声明他们要到导出的包以供其他模块使用。但是

java.security.jgss

模块的module-info.class文件中并未声明
在这里插入图片描述

解决方式

  1. 在JVM的启动参数上增加以下参数--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED
  2. 升级hadoop-common版本到3.3.6 在该版本中KerberosUtil并未通过反射访问sun.security.krb5.Config
  • hadoop-common:3.1.3版本的KerberosUtil在这里插入图片描述
  • hadoop-common:3.3.6版本的KerberosUtil在这里插入图片描述

扩展

利用JAAS机制认证Kerberos,不再使用

UserGroupInformation

进行认证
增加一个配置文件gss-jaas.conf

com.sun.security.jgss.initiate{
   com.sun.security.auth.module.Krb5LoginModule required
   doNotPrompt=true
   useTicketCache=true
   useKeyTab=true
   renewTGT=true
   debug=true
   ticketCache="/kerberos-tmp/krb5cc_1000"
   keyTab="D:\\xxxx\\hive.service.keytab"
   principal="hive/xxxx@xxxx";
 };
privatevoidauthKerberos1(){// 指定gss-jaas.conf文件路径System.setProperty("java.security.auth.login.config","D:\\xxx\\gss-jaas.conf");// System.setProperty("sun.security.jgss.debug", "true");System.setProperty("javax.security.auth.useSubjectCredsOnly","false");String confPath ="D:\\xxxx\\krb5.conf";System.setProperty("java.security.krb5.conf", confPath);}

思考

有时我们开发的系统是要部署到客户现场使用,而客户现场使用的hive版本和司内环境使用的版本可能不同。一般在程序开发时使用的依赖版本皆是定义在pom文件中,一旦打包之后依赖的版本就是固定的。因此需要考虑程序可适配不同的hive-jdbc版本,能够动态加载不同版本的hive-jdbc,或者在项目启动时可以指定额外的hive-jdbc驱动包

  • 使用类加载器在程序运行时动态从指定路径读取并加载指定的驱动jar包
URLClassLoader loader =newURLClassLoader(urls,Thread.currentThread().getContextClassLoader());Class.forName(driverName,true, loader);
  • 在项目启动时能够将指定的目录中的jar包放到类路径中
标签: java hive

本文转载自: https://blog.csdn.net/weixin_44144092/article/details/138359881
版权归原作者 只俗不凡 所有, 如有侵权,请联系我们删除。

“java通过Kerberos认证方式连接hive”的评论:

还没有评论