title: How to get Hadoop client to user correct credentials in a secure (Kerberos) clusters
body: <p>I have a Hadoop (CDH412) cluster setup that has been enabled to authenticate and authorize with Kerberos.  I got everything to work fine (Hdfs, mapred, zookeeper, hbase, hive, etc).  I am, however, having an issue with accessing hdfs data from within a java app.</p>
  
  <p>My Java app is a service that runs in the background.  Due to this, no password can be entered, I have to use a keytab file.  Should not be a problem.  It works fine if I do a 'kinit' first, ala...</p>
  
  <pre><code>kinit -kt /home/fred/kerberostest/krb5.keytab myprinc/myserver.com@MY.REALM
  </code></pre>
  
  <p>However, if I try to do this in java code (I have read that LoginContext.logon will do the same thing as the kinit), it fails.</p>
  
  <p>To try to test this, I have written the following code snippet....</p>
  
  <pre><code>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();
  </code></pre>
  
  <p>My jaas.conf file looks like this.....</p>
  
  <pre><code>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;
  }
  </code></pre>
  
  <p>When I run the java code, above, the LoginContext.login appears to work correctly.... I get a debug statement that says </p>
  
  <pre><code>Login successful for user myprinc/myserver.com@MY.REALM using keytab file /home/fred/kerberostest/krb5.keytab
  </code></pre>
  
  <p>When the code tries to open the HDFS file (fs.open), however, the app fails with an PriviledgedActionException, stating:</p>
  
  <pre><code>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)]
  </code></pre>
  
  <p>So, it is trying to use "fred" (my linux logon) to access these files, instead of my principal information from the keytab file.  Again, if I do a kinit first, it works fine.... but isn't LoginContext supposed to do the same thing?</p>
  
  <p>Note: This is an ActiveDirectory "version" of Kerberos.  It is not using trusts... just directly to ActiveDirectory.</p>