jdbc通过kerberos认证连接hive

这篇具有很好参考价值的文章主要介绍了jdbc通过kerberos认证连接hive。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

pom依赖添加hive-jdbc

根据实际情况添加依赖,主要看服务器hive版本

<dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>2.1.1-cdh6.3.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-slf4j-impl</artifactId>
                </exclusion>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

认证文件

配置文件krb5.conf,认证文件krb5.keytab,一般由服务器生成后获取

放到resources目录下

 jdbc通过kerberos认证连接hive

 文章来源地址https://www.toymoban.com/news/detail-499596.html

认证方法KerberosAuth.java

指定krb5配置文件:krb5.conf,根据实际情况替换

认证文件:krb5.keytab,根据实际情况替换

认证用户:hive,根据实际情况修改

这里是通过将配置文件和认证文件拷贝到临时目录进行认证,可以根据需要指定固定目录认证

public class KerberosAuth {
    private static Logger log = LoggerFactory.getLogger(KerberosConnect.class);
    // kerberos配置文件,从服务上获取
    private static String krbConfig="krb5.conf";
    // kerberos认证文件
    private static String krbKeytab="krb5.keytab";
    // kerberos认证用户
    private static String krbUser="hive";

    private static String tempDir;

    public static void init(){
        initkerberos();
    }

    public static void  initkerberos() {
        log.info("Kerberos 登陆验证");
        try {
            // java临时目录,window为C:\Users\登录用户\AppData\Local\Temp\,linux为/tmp,需要根据情况添加斜杠
            String javaTempDir = System.getProperty("java.io.tmpdir");
            // 将之前的临时认证文件删除
//            deleteTempDir();
            tempDir = (javaTempDir.lastIndexOf(File.separator)==javaTempDir.length()-1?javaTempDir:javaTempDir+File.separator)+"tomcat_"+System.currentTimeMillis();
            String configPath = krbConfig.contains(File.separator) ? krbConfig : getTempPath(tempDir,krbConfig);
            String keytabPath = krbKeytab.contains(File.separator) ? krbKeytab : getTempPath(tempDir,krbKeytab);
            log.debug(configPath);
            log.debug(keytabPath);
            System.setProperty("java.security.krb5.conf", configPath);//设置krb配置文件路径,注意一定要放在Configuration前面,不然不生效
            Configuration conf = new Configuration();
            conf.set("hadoop.security.authentication", "Kerberos");//设置认证模式Kerberos
            UserGroupInformation.setConfiguration(conf);
            UserGroupInformation.loginUserFromKeytab(krbUser, keytabPath);//设置认证用户和krb认证文件路径
            log.info("Kerberos 验证成功");
        } catch (Exception e) {
            log.error("Kerberos 验证失败", e);
        }

    }
 /**
     * 根据文件名称获取文件路径临时路径(解决jar包不支持获取resource下文件问题)
     * @param tempPath 临时目录
     * @param fileName 文件名称
     * @return 文件临时路径
     */
    public static String  getTempPath(String tempPath, String fileName){
//        ClassPathResource krbConfigRes = new ClassPathResource(fileName);
//        String path = this.getClass().getClassLoader().getResource(fileName);
        InputStream in = KerberosConnect.class.getResourceAsStream("/" + fileName);
        String krbConfigFileTempPath = tempPath+File.separator+fileName;
        File krbConfigFileTemp = new File(krbConfigFileTempPath);
        File tempPathFile = new File(tempPath);
        if (!tempPathFile.exists()) {
            tempPathFile.mkdir();
        }
        try {
            MyFileUtils.copyInputStreamToFile(in,krbConfigFileTemp);
        } catch (Exception e) {
            log.error("getTempPath",e);
        }
        return krbConfigFileTemp.getPath();
    }

}

 

HiveUtils

kerberos认证需要在获取Connection 之前

而且jdb连接格式如下

jdbc:hive2://10.**.**.**:10000/test_db;principal=hive/hostname@HADOOP.COM

  • 说明

   principal:

        hive/hostname:这里指定认证的hive的hostname

        @HADOOP.COM:realms和krb5.conf文件里一致即可

import com.gientech.schedule.config.KerberosConnect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.*;

public class HiveUtils {
    private static Logger logger = LoggerFactory.getLogger(HiveUtils.class.getName());

    private static String driverName = "org.apache.hive.jdbc.HiveDriver";
    private static String url = "jdbc:hive2://10.10.10.10:10000/test_db;principal=hive/hostname@HADOOP.COM";//端口默认10000

    /**
     * 获取Connection
     * @return conn
     * @throws SQLException
     * @throws ClassNotFoundException
     */

    public static Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            KerberosAuth.init();
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            logger.info("获取数据库连接失败!");
            throw e;
        }
        return conn;
    }

    // 创建数据库
    public static void createDatabase(String databaseName) throws Exception {
        String sql = "create database "+databaseName;
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        stmt.execute(sql);
        closeConnection(conn);
        closeStatement(stmt);
    }

    // 查询所有数据库
    public static void showDatabases() throws Exception {
        String sql = "show databases";
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
            logger.info(rs.getString(1));
        }
        closeConnection(rs,stmt,conn);
    }

    /**
     * 创建表(分割符为“,”)
     * 如create table tableName(name string,sex string) row format delimited fields terminated by ','
     * @param sql
     * @throws Exception
     */
    public static void createTable(String sql) throws Exception {
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        stmt.execute(sql);
        closeConnection(conn);
        closeStatement(stmt);
    }

    // 查询所有表
    public static void showTables() throws Exception {
        String sql = "show tables";
        logger.info("Running: " + sql);
        getConnection();
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
            logger.info(rs.getString(1));
        }
        closeConnection(rs,stmt,conn);
    }

    // 查看表结构
    public static void descTable(String tableName) throws Exception {
        String sql = "desc formatted "+tableName;
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
            logger.info(rs.getString(1) + "\t" + rs.getString(2));
        }
        closeConnection(rs,stmt,conn);
    }

    // 加载数据(请确保文件权限)
    public static void loadData(String filePath,String tableName) throws Exception {
        String sql = "load data inpath '" + filePath + "' into table tableName";
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        stmt.execute(sql);
        closeConnection(conn);
        closeStatement(stmt);
    }

    // 查询数据
    public static void selectData(String sql) throws Exception {
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        rs = stmt.executeQuery(sql);
        while (rs.next()) {
            logger.info(rs.getString(1));
        }
        closeConnection(rs,stmt,conn);
    }

    // 删除数据库
    public static void dropDatabase(String databaseName) throws Exception {
        String sql = "drop database if exists "+databaseName;
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        stmt.execute(sql);
        closeConnection(conn);
        closeStatement(stmt);
    }

    // 删除数据库表
    public static void deopTable(String tableName) throws Exception {
        String sql = "drop table if exists "+tableName;
        logger.info("Running: " + sql);
        Connection conn = getConnection();
        Statement stmt = conn.createStatement();
        stmt.execute(sql);
        closeConnection(conn);
        closeStatement(stmt);
    }


    public static Map<String,Object> queryMapBySql(String sql){
        //定义数据库连接
        Connection conn = null;
        //定义PreparedStatement对象
        PreparedStatement ps = null;
        //定义查询的结果集
        ResultSet rs = null;
        try {
            conn = getConnection();
            //定义执行的sql语句
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            return getMapFromResultSet(rs);
        } catch (Exception e) {
            logger.info("queryDataListBySql"+e.getMessage());
        }finally {
            closeConnection(rs,ps,conn);
        }
        return Collections.emptyMap();
    }

    /**
     * 关闭ResultSet、Statement、Connection
     *
     * @param rs
     * @param stmt
     * @param con
     */

    public static void closeConnection(ResultSet rs, Statement stmt, Connection con) {
        closeResultSet(rs);
        closeStatement(stmt);
        closeConnection(con);
    }

    /**
     * 关闭ResultSet
     *
     * @param rs
     */

    public static void closeResultSet(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                logger.info(e.getMessage());
            }
        }
    }

    /**
     * 关闭Statement
     *
     * @param stmt
     */

    public static void closeStatement(Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
        }
    }

    /**
     * 关闭Connection
     *
     * @param con
     */

    public static void closeConnection(Connection con) {
        if (con != null) {
            try {
                con.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
        }
    }

    /**
     * 将resultset结果转为sonObject
     * @param rs ResultSet
     * @return List
     * @throws SQLException 异常
     */
    public static Map<String,Object> getMapFromResultSet(ResultSet rs)
            throws SQLException {
        Map<String,Object> hm = new HashMap();
        ResultSetMetaData rsmd = rs.getMetaData();
        int count = rsmd.getColumnCount();// 获取列的数量
        while(rs.next()) {
            for (int i = 1; i <= count; i++) {
                String key = rsmd.getColumnLabel(i);
                Object value = rs.getObject(i);
                hm.put(key, value);
            }
        }
        return hm;
    }

    public static List<Map<String,Object>> queryListBySql(String sql){
        //定义数据库连接
        Connection conn = null;
        //定义PreparedStatement对象
        PreparedStatement ps = null;
        //定义查询的结果集
        ResultSet rs = null;
        try {
            conn = getConnection();
            //定义执行的sql语句
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            return getListFromResultSet(rs);
        } catch (Exception e) {
            logger.info("queryDataListBySql"+e.getMessage());
        }finally {
            closeConnection(rs,ps,conn);
        }
        return Collections.emptyList();
    }

    /**
     * 将resultset结果转为list
     * @param rs ResultSet
     * @return List
     * @throws SQLException 异常
     */
    private static List<Map<String,Object>> getListFromResultSet(ResultSet rs)
            throws SQLException {
        List<Map<String,Object>> results= new ArrayList<>();//结果数据
        ResultSetMetaData metaData = rs.getMetaData(); // 获得列的结果
        List<String> colNameList= new ArrayList<>();
        int cols_len = metaData.getColumnCount(); // 获取总的列数
        for (int i = 0; i < cols_len; i++) {
            colNameList.add(metaData.getColumnName(i+1));
        }
        while (rs.next()) {
            Map<String, Object> map= new HashMap<>();
            for(int i=0;i<cols_len;i++){
                String key=colNameList.get(i);
                Object value=rs.getString(colNameList.get(i));
                map.put(key, value);
            }
            results.add(map);
        }
        return results;
    }

    public static void main(String[] args) throws Exception {
        String sql = "SELECT * FROM `t1` LIMIT 1";
        List<Map<String, Object>> maps = queryListBySql(sql);
        logger.info(maps.toString());
    }
}

 

执行main方法查询效果如下

jdbc通过kerberos认证连接hive

常见问题

1、Peer indicated failure: Unsupported mechanism type GSSAPI

  hive服务中关闭了kerberos,但是连接中使用了kerberos认证,导致此错误

2、Unsupported mechanism type PLAIN

 代表hive服务已经开启了kerberos,但是链接字符串未使用kerberos认证方式(principal=hive/hostname@HADOOP.COM),所以报错。

 

 

到了这里,关于jdbc通过kerberos认证连接hive的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 访问连接Hive的Kerberos认证前提

    The reason why authentication needs to be added when connecting to Hive in the Java code is that Hive is a distributed data processing system that is typically deployed in a multi-user environment, where access to data is controlled by policies and permissions. Therefore, to ensure the security and integrity of the data, it is necessary to authenticate users

    2024年02月07日
    浏览(47)
  • 【dbeaver】win环境的kerberos认证和Clouders/cdh集群中Kerberos认证使用Dbeaver连接Hive、Impala和Phoenix

    1.1 下载安装MIT KERBEROS客户端 MIT KERBEROS 下载较新的版本即可。 下载之后一路默认安装即可。 注意:不要修改软件安装位置。 修改系统环境变量中的Path。将刚刚的安装路径置顶。(不置顶,也要比 %JAVA_HOME%bin 和 anaconda 相关的高) 使用CMD命令确认下: 1.2 修改 krb5.conf 文件并

    2024年02月02日
    浏览(54)
  • 企业级大数据安全架构(十)DBeaver连接Hive的Kerberos认证配置

    1.配置本地hosts 因为Kerberos认证过程及集群服务中,很多是以主机名的形式进行访问的,所以工作机要设置hosts. 域名映射,我们通过部署CDH的集群的每一台机器都已经配置了host(文件为/etc/hosts),工作机也需要配置window的host文件,如果提示无法修改,一般是需要管理员权限的原

    2024年02月21日
    浏览(46)
  • Hive连接异常:无法通过JDBC连接打开客户端传输(JDBC Uri: jdbc:hive2:// 大数据)

    Hive连接异常:无法通过JDBC连接打开客户端传输(JDBC Uri: jdbc:hive2:// 大数据) 在大数据领域中,Hive是一个常用的数据仓库解决方案,可以用于处理和分析大规模的结构化数据。然而,在使用Hive时,我们有时会遇到一些连接问题。其中之一就是\\\"Hive连接报错:Could not open clien

    2024年02月08日
    浏览(45)
  • Java(115)Java通过jdbc接口连接hive3.1.2

    hive版本:3.1.2 jdbc:hive-jdbc-uber-2.6.5.0-292.jar 下载驱动地址:https://github.com/timveil/hive-jdbc-uber-jar/releases/tag/v1.9-2.6.5 CREATE TABLE regre_one.hive2_varchar( ID int, aes varchar(1000), sm4 varchar(1000), sm4_a varchar(1000), email varchar(1000), phone varchar(1000), ssn varchar(1000), military varchar(1000), passport varchar(1000)

    2024年02月05日
    浏览(53)
  • Kerberos安全认证-连载10-Hive Kerberos 安全配置及访问

    目录 1.Hive 配置 Kerberos 2. Hive Cli使用Kerberos ​​​​​​​3. Hive beeline使用Kerberos ​​​​​​​​​​​​​​4. JDBC访问Kerberos认证Hive ​​​​​​​5. Spark访问Kerberos认证Hive ​​​​​​​​​​​​​​6. Flink访问Kerberos认证Hive 技术连载系列,前面内容请参考前面

    2024年02月13日
    浏览(48)
  • elasticsearch添加kerberos认证完整操作流程

    kerberos认证的教程网上有很多,但是es的真的找遍全网都很少有详细的教程!我苦读官网,到处搜罗零碎信息,才终于完成es的kerberos认证。 在我跟着官网步骤勤勤恳恳操作却还是不行的时候,才突然发现基础版并不支持kerberos认证。所以我们需要升级白金版,而白金版是付费

    2024年01月17日
    浏览(50)
  • Failed to load driver class com.mysql.cj.jdbc.Driver异常-IntellIJ Idea-后端项目连接数据库_添加MyBatis依赖配置问题

    前言 :后端项目连接数据库配置时,添加了如下application.properties的数据库连接配置 项目点击运行,就出现以下系列问题 这种情况通常是由于以下原因之—引起的: 1.没有在项目中引入mysql-connectorjar包,或者引入的包版本与JDBC驱动不匹配。解决方法:在项目pom.xml中添加相关依

    2024年02月05日
    浏览(81)
  • 用户认证-Kerberos的介绍和使用(Hadoop、Hive、数仓流程、Presto、Kylin集成配置)

    概述 Kerberos是一种计算机网络认证协议,用来在非安全网络中,对个人通信以安全的手段进行 身份认证 , 它允许某实体在非安全网络环境下通信,向另一个实体以一种安全的方式证明自己的身份 。这个词又指麻省理工学院为这个协议开发的一套计算机软件。软件设计上采用

    2024年02月02日
    浏览(56)
  • SpringBoot项目连接,有Kerberos认证的Kafka

    Kerberos是一种计算机网络认证协议 ,其设计目标是通过密钥系统为网络中通信的客户机(Client)/服务器(Server)应用程序提供严格的身份验证服务,确保通信双方身份的真实性和安全性。不同于其他网络服务,Kerberos协议中不是所有的客户端向想要访问的网络服务发起请求,他就能

    2024年01月22日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包