我有一个 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) 时,应用程序失败并出现 PriviledgedActionException,说明:
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“版本”。它不使用信任...只是直接到 ActiveDirectory。