Question

We have a kerberos domain at my company and I'm running a few of the Java/Kerberos examples. The question I have is around the login mechanism from the server's perspective. When running the server example GssServer.java, I need to get a javax.security.auth.Subject; in the supplied code this is via a LoginContext thus:

// Create a LoginContext with a callback handler and login
LoginContext context = new LoginContext(name, new TextCallbackHandler());
context.login();

Subject subject = context.getSubject();

This is all OK and when I run the example I see a lovely login prompt. However my issue is that this is not 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 GssServer example, the problem is my server (read: service) should not need to authenticate itself to the KDC in order to present its service to clients. Access to the server-side keytab file should be sufficient to do this. So for the example config:

//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";
};

And in the Java 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);

The trouble with this is that the server information in the jaas-krb5.conf file is not available unless I authenticate myself via the line:

Jaas.loginAndAction("server", action);     

I shouldn't have to go thru this authentication! But if I don't authenticate myself, I end up with:

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.<init>(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.<init>(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

It's not surprising that there is a problem. After all, unless I have a handle on the server subject, how can I know where my keytab is, or what service I am providing?

So my question is: how can I tell the GSS API about the keytab/service without authenticating myself in code?

Was it helpful?

Solution

OK. So this turns out to be extremely easy assuming you know that the keytab file can be used instead of authentication. This is outlined a bit in the JavaDoc for Krb5LoginModule

Basically, if I

loginAndAction("anything", action)

Then my config should look like:

//jaas-krb5.conf
anything {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    doNotPrompt=true
    keyTab="/home/myusr/my-server.keytab"
    principal="myserv/mymachine.some.domain";
};

The important bit is the addition of doNotPrompt=true. When this property is set, the server code uses the information in the keytab

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top