java如何通過Kerberos認(rèn)證方式連接hive
在數(shù)據(jù)源管理功能中,需要適配mysql、postgresql、hive等數(shù)據(jù)源。
mysql和postgresql連接方式一致,只需要驅(qū)動(dòng)和jdbcurl即可,而hive背后是大數(shù)據(jù)集群,多采用Kerberos的方式保護(hù)集群環(huán)境,要想與大數(shù)據(jù)集群正常交互,需要經(jīng)過kdc認(rèn)證獲取ticket,因此獲取hive連接前需要先通過Kerberos認(rèn)證
Java實(shí)現(xiàn)Kerberos認(rèn)證
主要方法
# 從keytab文件中加載用戶標(biāo)識(shí)并登錄 org.apache.hadoop.security.UserGroupInformation#loginUserFromKeytab
依賴
kerberos相關(guān)配置文件:krb5.conf、keytab文件從大數(shù)據(jù)集群管理員那獲取
依賴:hive-jdbc:3.1.3(hive安裝目錄中帶有該驅(qū)動(dòng)包,可查看使用的版本)、hadoop-common:3.3.6,版本需和hive服務(wù)版本一致,在springboot3的框架下需要排除以下依賴,否則啟動(dòng)報(bào)錯(cuò)
<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 = new Configuration(); configuration.set("hadoop.security.authentication", "KERBEROS"); UserGroupInformation.setConfiguration(configuration); try { UserGroupInformation.loginUserFromKeytab(principal, keytabPath); } catch (IOException e) { log.error("authKerberos exception", e); throw new BizException("kerberos認(rèn)證失敗"); }
除了上述方式外,也可采用JAAS可插拔的認(rèn)證模塊進(jìn)行Kerberos認(rèn)證
續(xù)期
Kerberos的ticket存在有效期,過期后導(dǎo)致服務(wù)不可用
Kerberos ticket存在兩種有效期,ticket timelife(票據(jù)生命周期)、renewable lifetime(可再生周期)
- ticket的時(shí)間超過ticket lifetime時(shí),該ticket將不可用
- 在renewable lifetime的時(shí)間內(nèi),可以對(duì)即將過期的ticket進(jìn)行續(xù)期,超過renewable lifetime時(shí)間后,無法續(xù)期
- 例如kerb5.conf文件中的配置:ticket_lifetime = 24h renewable_lifetime = 7d,則在登錄后的24小時(shí)內(nèi),可以對(duì)即將過期的ticket進(jìn)行續(xù)期,距第一次登錄7天后,將不再允許續(xù)期
UserGroupInformation提供了認(rèn)證續(xù)期的私有方法UserGroupInformation#reloginFromKeytab(boolean)
,該方法有兩個(gè)觸發(fā)入口UserGroupInformation#checkTGTAndReloginFromKeytab
和UserGroupInformation#reloginFromKeytab()
值得注意的是
UserGroupInformation#loginUserFromKeytab
方法中會(huì)開啟異步任務(wù),定時(shí)觸發(fā)續(xù)期方法,觸發(fā)的續(xù)期方法即是
UserGroupInformation#reloginFromKeytab()
向線程池中提交續(xù)期的任務(wù)
也可以自定義觸發(fā)續(xù)期的邏輯, 定期觸發(fā)
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab()
連接hive
Kerberos認(rèn)證之后,使用hive-jdbc連接hive,之后與連接mysql、pg的方式無異,使用DriverManager或數(shù)據(jù)源連接池Hikari皆可
遇到的問題
一開始選擇hadoop-common
的版本是3.1.3
,執(zhí)行Kerberos認(rèn)證時(shí)報(bào)錯(cuò)
KerberosUtil
無法訪問sun.security.krb5.Config
(它在java.security.jgss
模塊中)。
分析
本項(xiàng)目采用的框架是spring boot3版本,最低要求的jdk版本是17,而Java在9之后引入了模塊化機(jī)制,模塊必須顯式聲明他們要到導(dǎo)出的包以供其他模塊使用。
但是java.security.jgss
模塊的module-info.class文件中并未聲明
解決方式
1.在JVM的啟動(dòng)參數(shù)上增加以下參數(shù)
--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED
2.升級(jí)hadoop-common
版本到3.3.6
在該版本中KerberosUtil
并未通過反射訪問sun.security.krb5.Config
hadoop-common:3.1.3
版本的KerberosUtil
hadoop-common:3.3.6
版本的KerberosUtil
擴(kuò)展
利用JAAS機(jī)制認(rèn)證Kerberos,不再使用UserGroupInformation
進(jìn)行認(rèn)證
增加一個(gè)配置文件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"; };
private void authKerberos1() { // 指定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); }
思考
有時(shí)我們開發(fā)的系統(tǒng)是要部署到客戶現(xiàn)場(chǎng)使用,而客戶現(xiàn)場(chǎng)使用的hive版本和司內(nèi)環(huán)境使用的版本可能不同。一般在程序開發(fā)時(shí)使用的依賴版本皆是定義在pom文件中,一旦打包之后依賴的版本就是固定的。因此需要考慮程序可適配不同的hive-jdbc版本,能夠動(dòng)態(tài)加載不同版本的hive-jdbc,或者在項(xiàng)目啟動(dòng)時(shí)可以指定額外的hive-jdbc驅(qū)動(dòng)包
- 使用類加載器在程序運(yùn)行時(shí)動(dòng)態(tài)從指定路徑讀取并加載指定的驅(qū)動(dòng)jar包
URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader()); Class.forName(driverName, true, loader);
- 在項(xiàng)目啟動(dòng)時(shí)能夠?qū)⒅付ǖ哪夸浿械膉ar包放到類路徑中
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot和VUE源碼直接整合打包成jar的踩坑記錄
這篇文章主要介紹了SpringBoot和VUE源碼直接整合打包成jar的踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03MyBatis如何實(shí)現(xiàn)多表查詢(多對(duì)一、一對(duì)多)
這篇文章主要給大家介紹了關(guān)于MyBatis如何實(shí)現(xiàn)多表查詢(多對(duì)一、一對(duì)多)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05springboot集成@DS注解實(shí)現(xiàn)數(shù)據(jù)源切換的方法示例
本文主要介紹了springboot集成@DS注解實(shí)現(xiàn)數(shù)據(jù)源切換的方法示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Java 堆內(nèi)存與棧內(nèi)存詳細(xì)介紹
這篇文章主要介紹了Java 堆內(nèi)存與棧內(nèi)存詳細(xì)介紹的相關(guān)資料,這里對(duì)java 的堆內(nèi)存和棧內(nèi)存進(jìn)行了詳細(xì)的分析,需要的朋友可以參考下2016-11-11實(shí)例講解String Date Calendar之間的轉(zhuǎn)換
下面小編就為大家?guī)硪黄獙?shí)例講解String Date Calendar之間的轉(zhuǎn)換。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07springboot + mybatis + druid + 多數(shù)據(jù)源的問題詳解
這篇文章主要介紹了springboot + mybatis + druid + 多數(shù)據(jù)源的問題詳解,示例代碼文字相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09SpringMVC通過RESTful結(jié)構(gòu)實(shí)現(xiàn)頁面數(shù)據(jù)交互
RESTFUL是一種網(wǎng)絡(luò)應(yīng)用程序的設(shè)計(jì)風(fēng)格和開發(fā)方式,基于HTTP,可以使用XML格式定義或JSON格式定義。RESTFUL適用于移動(dòng)互聯(lián)網(wǎng)廠商作為業(yè)務(wù)接口的場(chǎng)景,實(shí)現(xiàn)第三方OTT調(diào)用移動(dòng)網(wǎng)絡(luò)資源的功能,動(dòng)作類型為新增、變更、刪除所調(diào)用資源2022-08-08