如何使用 java 从安全的 kerberos 环境访问配置单元数据库

How to access hive database from secured kerberos environment using java


我在 kerberos 环境中使用 hadoop,我是 kerberos 的新手。我想使用 java 访问配置单元数据库,我浏览了配置单元官方网站,但他们提供了非常笼统的信息。
请有人给我具体的答案?

我认为 kerbrose 实现是一个非常庞大的概念,为了完成一项小任务而完成它可能会很耗时。
这是快速解决您的问题的方法!
要在安全环境中访问配置单元,请考虑以下事项:

- 要访问配置单元,您需要提供特定于该配置单元版本的所有 jar,如配置单元官方网站上的列表所示。
-下一步提供配置单元版本特定的驱动程序名称,例如对于配置单元服务器 2 "org.apache.hive.jdbc.HiveDriver"
- 提供配置单元连接 URL 例如jdbc:hive2://node.addr:10000/default;principal=hive/node.addr@ABCREALM.LOCAL
我们在连接URL中提供连接地址和安全认证。对于 kerberos,将有身份验证字符串,这是我们在 kerberos 实施时设置的 kerberos 原则。
此字符串与我们使用 beeline 连接到配置单元服务器时提供的字符串相同,例如直线-u "jdbc:hive2://node.addr:10000/default;principal=hive/node.addr@ABCREALM.LOCAL"
下面是一段小代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;

public class Connect {

    private static ResultSet res;

       public static void main(String[] args) throws Exception {
              Class.forName("org.apache.hive.jdbc.HiveDriver");
              System.out.println("Process started at:"+new Date());
              Connection con = DriverManager.getConnection("jdbc:hive2://node.addr:10000/default;principal=hive/node.addr@ABCREALM.LOCAL");

              Statement stmt = con.createStatement();
              stmt.execute("create table testTable (key string,col1 string)");
              System.out.println("Table Created successfully");
              con.close();
          }
    }

有了 Kerberos,事情就变得更复杂了。

任何jdbc代码之前的配置:

进口:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.log4j.Logger;

初始化配置代码:

Configuration systemConf = new Configuration();
        if (isLocalRun()) {
            LOG.info("Running on cluster, using hive-site.xml config");
            systemConf.addResource(new Path("/etc/hadoop/current/hive/hive-site.xml"));
        } else {
            LOG.info("Running from local computer, no hive-site.xml added, using only JDBC");
        }
        systemConf.set("hadoop.security.authentication", "Kerberos");
        UserGroupInformation.setConfiguration(systemConf);
        UserGroupInformation.loginUserFromKeytab(principal, keytabPath);

然后就可以连接了:

 try (Connection conn = DriverManager.getConnection(conf.hive().getConnectionString())) {
            HiveDatabaseMetaData metadata = (HiveDatabaseMetaData) conn.getMetaData();
            parseDatabase(hiveDatabase, conn, metadata, 
        }

Hive 的 Maven 依赖项jdbc 驱动程序

    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>2.0.0</version>
        <classifier>standalone</classifier>
    </dependency>
  • isLocalRun()= 这取决于你 运行 它是在你的计算机上还是直接在集群上
    • 当 运行ning 在集群上时,您需要添加 hive-site.xml(可以不同 路径比在这个例子中)与所有配置
    • 从本地使用 jdbc 连接字符串进行外部集群连接

可能您需要为 Kerberos 身份验证和相关应用程序配置设置环境, 另外,请按照驱动程序 options/settings 进行 Kerberos 身份验证:

  1. 根据您的环境设置设置 kinit(kerberos) 服务和 /etc/krb5.conf。
  2. 需要 Kerberos 服务器和数据库服务器的网络权限。
  3. 创建 jaas.conf 文件(在独立应用程序用户或应用程序服务器用户可访问的文件路径中)
  4. 按照上面的 jaas 配置文件放置密钥表。

如果它是独立的 java 应用程序,您可以按如下方式设置 sys 属性:

System.setProperty("java.security.auth.login.config","//jaas.conf");

如果是 Web 应用程序(可以通过编程方式设置 jaas 配置):

Java代码:

    //in getConnection method
    Configuration jaasConfig = createJaasConfig();
    Configuration.setConfiguration(jaasConfig);
    System.setProperty("java.security.auth.login.config", jaasConfig.toString());
    
    
private Configuration createJaasConfig() {

    String keytab = "/<your_key_tab_path>/myuser.keytab";


    // Create entry options.
    ImmutableMap<String, String> options = ImmutableMap.of(
            "com.sun.security.auth.module.Krb5LoginModule", "required",
            "doNotPrompt", "true",
            "useKeyTab", "true",
            "keyTab", "" + keytab,
            "principal", "myuser@SRILANKA.LK"
    );

    // Create entries.
    final AppConfigurationEntry[] entries = {
        new AppConfigurationEntry(
        Krb5LoginModule.class.getCanonicalName(),
        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
        options)
    };

    // Create configuration.
    return new Configuration() {
        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            return entries;
        }
    };

}