用于安全Hbase的Java客户端

用于安全Hbase的Java客户端,java,security,hadoop,hbase,kerberos,Java,Security,Hadoop,Hbase,Kerberos,嗨,我正在尝试为安全的hbase编写java客户端。 我还想从代码本身进行kinit,因为我使用的是usergroup信息类。 有人能指出我哪里出了问题吗 这是我尝试连接hbase的主要方法 我必须在configuration对象中添加配置,而不是使用xml,因为客户机可以位于任何位置 请参阅下面的代码: public static void main(String [] args) { try { System.setProperty(CommonConstan

嗨,我正在尝试为安全的hbase编写java客户端。 我还想从代码本身进行kinit,因为我使用的是usergroup信息类。 有人能指出我哪里出了问题吗

这是我尝试连接hbase的主要方法

我必须在configuration对象中添加配置,而不是使用xml,因为客户机可以位于任何位置

请参阅下面的代码:

    public static void main(String [] args) {
    try {
        System.setProperty(CommonConstants.KRB_REALM, ConfigUtil.getProperty(CommonConstants.HADOOP_CONF, "krb.realm"));
        System.setProperty(CommonConstants.KRB_KDC, ConfigUtil.getProperty(CommonConstants.HADOOP_CONF,"krb.kdc"));
        System.setProperty(CommonConstants.KRB_DEBUG, "true");

        final Configuration config = HBaseConfiguration.create();

        config.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, AUTH_KRB);
        config.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHORIZATION, AUTHORIZATION);
        config.set(CommonConfigurationKeysPublic.FS_AUTOMATIC_CLOSE_KEY, AUTO_CLOSE);
        config.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, defaultFS);
        config.set("hbase.zookeeper.quorum", ConfigUtil.getProperty(CommonConstants.HBASE_CONF, "hbase.host"));
        config.set("hbase.zookeeper.property.clientPort", ConfigUtil.getProperty(CommonConstants.HBASE_CONF, "hbase.port"));
        config.set("hbase.client.retries.number", Integer.toString(0));
        config.set("zookeeper.session.timeout", Integer.toString(6000));
        config.set("zookeeper.recovery.retry", Integer.toString(0));
        config.set("hbase.master", "gauravt-namenode.pbi.global.pvt:60000");
        config.set("zookeeper.znode.parent", "/hbase-secure");
        config.set("hbase.rpc.engine", "org.apache.hadoop.hbase.ipc.SecureRpcEngine");
        config.set("hbase.security.authentication", AUTH_KRB);
        config.set("hbase.security.authorization", AUTHORIZATION);
        config.set("hbase.master.kerberos.principal", "hbase/gauravt-namenode.pbi.global.pvt@pbi.global.pvt");
        config.set("hbase.master.keytab.file", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");
        config.set("hbase.regionserver.kerberos.principal", "hbase/gauravt-datanode2.pbi.global.pvt@pbi.global.pvt");
        config.set("hbase.regionserver.keytab.file", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");

        UserGroupInformation.setConfiguration(config);
        UserGroupInformation userGroupInformation = UserGroupInformation.loginUserFromKeytabAndReturnUGI("hbase/gauravt-datanode2.pbi.global.pvt@pbi.global.pvt", "D:/var/lib/bda/secure/keytabs/hbase.service.keytab");
        UserGroupInformation.setLoginUser(userGroupInformation);

        User user = User.create(userGroupInformation);

        user.runAs(new PrivilegedExceptionAction<Object>() {

            @Override
            public Object run() throws Exception {
                HBaseAdmin admins = new HBaseAdmin(config);

                if(admins.isTableAvailable("ambarismoketest")) {
                    System.out.println("Table is available");
                };

                HConnection connection = HConnectionManager.createConnection(config);

                HTableInterface table = connection.getTable("ambarismoketest");



                admins.close();
                System.out.println(table.get(new Get(null)));
                return table.get(new Get(null));
            }
        });
        System.out.println(UserGroupInformation.getLoginUser().getUserName());


    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

任何提示都会有帮助。

不确定您是否仍然需要帮助。我认为您的代码片段中缺少设置“hadoop.security.authentication”属性

我使用以下代码片段连接到安全HBase(在CDH5上)。你可以试一试

config.set("hbase.zookeeper.quorum", zookeeperHosts);
config.set("hbase.zookeeper.property.clientPort", zookeeperPort);
config.set("hadoop.security.authentication", "kerberos");
config.set("hbase.security.authentication", "kerberos");
config.set("hbase.master.kerberos.principal", HBASE_MASTER_PRINCIPAL);
config.set("hbase.regionserver.kerberos.principal", HBASE_RS_PRINCIPAL);

UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab(ZOOKEEPER_PRINCIPAL,ZOOKEEPER_KEYTAB);

HBaseAdmin admins = new HBaseAdmin(config);
TableName[] tables  = admins.listTableNames();

for(TableName table: tables){
    System.out.println(table.toString());
}

上面的方法很有效,但是我看到很多人在配置对象中设置所有正确的属性时都很吃力。我没有找到一个事实上的列表,确切地列出您需要什么和不需要什么,而且它非常依赖于您的集群配置

可靠的方法是在类路径中有一份HBase配置的副本,因为您的客户端可以在您提到的任何地方。然后可以将资源添加到对象中,而不必指定所有属性

Configuration conf = HBaseConfiguration.create();
conf.addResource("core-site.xml");
conf.addResource("hbase-site.xml");
conf.addResource("hdfs-site.xml");
以下是支持这种方法的一些来源: ,

还请注意,这种方法并不限制您实际使用内部Zookeeper主体和密钥表,即您可以为应用程序或Active Directory用户创建密钥表,并将内部生成的密钥表留给守护进程在它们之间进行身份验证。

我认为最好的方法是

in Jdk 1.8, you need set 
"System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");"

config.set("hbase.zookeeper.quorum", zookeeperHosts);
config.set("hbase.zookeeper.property.clientPort", zookeeperPort);
config.set("hadoop.security.authentication", "kerberos");
config.set("hbase.security.authentication", "kerberos");
config.set("hbase.master.kerberos.principal", HBASE_MASTER_PRINCIPAL);
config.set("hbase.regionserver.kerberos.principal", HBASE_RS_PRINCIPAL);
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
UserGroupInformation.setConfiguration(config);
UserGroupInformation.loginUserFromKeytab(ZOOKEEPER_PRINCIPAL,ZOOKEEPER_KEYTAB);

HBaseAdmin admins = new HBaseAdmin(config);
TableName[] tables  = admins.listTableNames();

for(TableName table: tables){
    System.out.println(table.toString());
}

quote:
http://hbase.apache.org/book.html#trouble.client 
question: 142.9 
要使代码正常工作,您不必更改本文顶部所写代码的任何行,只需使您的客户端能够访问完整的HBase配置即可。这只意味着将运行的类路径更改为:

/opt/cloudera/parcels/CDH-5.3.0-1.cdh5.3.0.p0.30/lib/hbase/conf:target/scala-2.11/hbase-assembly-1.0.jar 这将使一切顺利进行。它特定于CDH 5.3,但您可以根据集群配置对其进行调整

PS在这方面不需要:

conf.addResource("core-site.xml");
conf.addResource("hbase-site.xml");
conf.addResource("hdfs-site.xml");
因为HBaseConfiguration已经

  public static Configuration addHbaseResources(Configuration conf) {
conf.addResource("hbase-default.xml");
conf.addResource("hbase-site.xml");

我试着用GSSAPI实现运行它,但仍然没有成功:(你能分享你完整的工作代码或Github链接吗?你能回答这个问题吗
  public static Configuration addHbaseResources(Configuration conf) {
conf.addResource("hbase-default.xml");
conf.addResource("hbase-site.xml");