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/[email protected]",
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?