title: kerberos from Java - getting a Subject for the currently authenticated user
body: <p>We have a kerberos domain at my company and I'm running a few of the Java/Kerberos <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/lab/part2.html" rel="noreferrer">examples</a>. The question I have is around the login mechanism from the server's perspective. When running the server example <code>GssServer.java</code>, I need to get a <code>javax.security.auth.Subject</code>; in the supplied code this is via a <code>LoginContext</code> thus:</p>
  
  <pre><code>// Create a LoginContext with a callback handler and login
  LoginContext context = new LoginContext(name, new TextCallbackHandler());
  context.login();
  
  Subject subject = context.getSubject();
  </code></pre>
  
  <p>This is all OK and when I run the example I see a lovely login prompt. However my issue is that this is <strong>not</strong> really how my server will run and nor how I've been led to understand how I should be presenting up services from within a kerberos domain. In the <code>GssServer</code> example, the problem is my server (read: service) should <strong>not need to authenticate itself</strong> to the <code>KDC</code> in order to present its service to clients. Access to the server-side <code>keytab</code> file should be sufficient to do this. So for the example config:</p>
  
  <pre><code>//jaas-krb5.conf
  server {
      com.sun.security.auth.module.Krb5LoginModule required
      useKeyTab=true
      storeKey=true
      keyTab="/home/myusr/my-server.keytab"
      principal="myserv/mymachine.some.domain";
  };
  </code></pre>
  
  <p>And in the Java code:</p>
  
  <pre><code>GSSManager manager = GSSManager.getInstance();
  Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
  GSSName gssName = manager.createName("myserv/mymachine.some.domain@THE.REALM.COM", 
                                       GSSName.NT_HOSTBASED_SERVICE);
  GSSCredential serverCreds = manager.createCredential(gssName,
                                       GSSCredential.DEFAULT_LIFETIME,
                                       krb5Mechanism,
                                       GSSCredential.ACCEPT_ONLY);
  </code></pre>
  
  <p>The trouble with this is that the <code>server</code> information in the <code>jaas-krb5.conf</code> file is not available <em>unless</em> I authenticate myself via the line:</p>
  
  <pre><code>Jaas.loginAndAction("server", action);     
  </code></pre>
  
  <p>I shouldn't have to go thru this authentication! But if I don't authenticate myself, I end up with: </p>
  
  <pre><code>Exception in thread "main" GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
      at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:188)
      at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:73)
      at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:77)
      at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:149)
      at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:389)
      at sun.security.jgss.GSSCredentialImpl.&lt;init&gt;(GSSCredentialImpl.java:45)
      at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:102)
      at gsa.hk.GssServer$GssServerAction.run(GssServer.java:79)
      at gsa.hk.GssServer.main(GssServer.java:57)
  Caused by: javax.security.auth.login.LoginException: No LoginModules configured for com.sun.security.jgss.accept
      at javax.security.auth.login.LoginContext.init(LoginContext.java:256)
      at javax.security.auth.login.LoginContext.&lt;init&gt;(LoginContext.java:403)
      at sun.security.jgss.LoginUtility.login(LoginUtility.java:72)
      at sun.security.jgss.krb5.Krb5Util.getKeysFromSubject(Krb5Util.java:205)
      at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:184)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:181)
      ... 8 more
  </code></pre>
  
  <p>It's not surprising that there is a problem. After all, unless I have a handle on the <code>server</code> subject, how can I know where my <code>keytab</code> is, or what service I am providing?</p>
  
  <p>So my question is: <strong>how can I tell the <code>GSS API</code> about the keytab/service without authenticating myself in code?</strong> </p>