Java 如何在安全(Kerberos)集群中获得Hadoop客户端到用户的正确凭据

Java 如何在安全(Kerberos)集群中获得Hadoop客户端到用户的正确凭据,java,hadoop,active-directory,kerberos,Java,Hadoop,Active Directory,Kerberos,我有一个Hadoop(CDH412)集群设置,它已启用Kerberos进行身份验证和授权。我把一切都准备好了(Hdfs、mapred、zookeeper、hbase、hive等)。然而,我在java应用程序中访问hdfs数据时遇到了问题 我的Java应用程序是一个在后台运行的服务。由于这个原因,没有密码可以输入,我必须使用一个键表文件。这应该不是问题。如果我先做一个“kinit”就行了,阿拉 kinit -kt /home/fred/kerberostest/krb5.keytab myprin

我有一个Hadoop(CDH412)集群设置,它已启用Kerberos进行身份验证和授权。我把一切都准备好了(Hdfs、mapred、zookeeper、hbase、hive等)。然而,我在java应用程序中访问hdfs数据时遇到了问题

我的Java应用程序是一个在后台运行的服务。由于这个原因,没有密码可以输入,我必须使用一个键表文件。这应该不是问题。如果我先做一个“kinit”就行了,阿拉

kinit -kt /home/fred/kerberostest/krb5.keytab myprinc/myserver.com@MY.REALM
但是,如果我尝试在java代码中执行此操作(我已经读到LoginContext.logon将执行与kinit相同的操作),它将失败

为了测试这一点,我编写了以下代码片段

System.setProperty("java.security.krb5.realm", "MY.REALM");
System.setProperty("java.security.kdc", "kdc.server.com");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.security.auth.login.config", "/home/fred/kerberostest/jaas.conf");

LoginContext context = new LoginContext("Client");
context.login();

Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);

InputStream in = fs.open(new Path("/mytestfile"));
int b = in.read();
in.close();
我的jaas.conf文件如下所示

Client {
   com.sun.security.auth.module.Krb5LoginModule required
   debug=true
   useKeyTab=true
   keyTab="/home/fred/kerberostest/krb5.keytab"
   principal="myprinc/myserver.com@MY.REALM"
   useTicketCache=false;
}
当我运行上面的java代码时,LoginContext.login似乎工作正常。。。。我得到一个调试语句,它说

Login successful for user myprinc/myserver.com@MY.REALM using keytab file /home/fred/kerberostest/krb5.keytab
但是,当代码尝试打开HDFS文件(fs.open)时,应用程序会失败,并出现PriviledEdActionException,声明:

ERROR security.UserGroupInformation: PriviledgedActionException as :fred (auth:KERBEROS) cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
因此,它试图使用“fred”(我的linux登录)来访问这些文件,而不是使用keytab文件中的主要信息。再说一次,如果我先做一个kinit,它很好用。。。。但是LoginContext不应该做同样的事情吗


注意:这是Kerberos的ActiveDirectory“版本”。这不是使用信托。。。直接转到Active Directory。

我将把这归咎于我们的Active Directory实现。我用麻省理工学院的Kerberos做了这件事,效果很好。关闭。

属性名称不应该是java.security.krb5.kdc而不是java.security.kdc,否则您会得到:由:KrbException引起:系统属性java.security.krb5.kdc和java.security.krb5.realm都必须设置,或者两者都不必设置。我的测试显示还应该有分号“;”作为jaas.conf文件中的最后一个字符。您对哪个Kerberos实现有问题?为了澄清,我设置的所有内容都是正确的。active directory上的人员没有正确设置主体。当我创建自己的MIT Kerberos时,一切都正常工作,这帮助广告人员了解他们需要做什么。