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