Hadoop (CDH412) クラスターのセットアップを使用して、Kerberos での認証と承認を有効にしています。すべて正常に動作するようになりました (Hdfs、mapred、zookeeper、hbase、hive など)。ただし、Java アプリ内から hdfs データにアクセスする際に問題が発生しています。
私の Java アプリは、バックグラウンドで実行されるサービスです。このため、パスワードを入力できません。keytab ファイルを使用する必要があります。問題になることはありません。最初に '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)]
そのため、keytab ファイルからのプリンシパル情報の代わりに、「fred」(私の Linux ログオン) を使用してこれらのファイルにアクセスしようとしています。繰り返しますが、最初に kinit を実行すると、正常に動作します....しかし、LoginContext は同じことをするはずではありませんか?
注: これは、Kerberos の ActiveDirectory "バージョン" です。信頼を使用していません... ActiveDirectoryに直接接続するだけです。