Kerberos with Java

I am trying to login to kerberos kdc with Java. But Java throws an exception. The login seems to be successful, but something stops the login. I do not know why? Does anyone have a solution to this problem? Here is my java system output:

Debug is true storeKey false useTicketCache true useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is true principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false Refreshing Kerberos configuration Acquire TGT from Cache Principal is null null credentials from Ticket Cache [Krb5LoginModule] user entered username: kadirb principal is kadirb@EXAMPLE.COM Commit Succeeded Exception in thread "main" java.lang.Error: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER) at KerberosTicketRetriever$TicketCreatorAction.run(KerberosTicketRetriever.java:76) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAsPrivileged(Subject.java:473) at KerberosTicketRetriever.retrieveTicket(KerberosTicketRetriever.java:179) at KerberosTicketRetriever.main(KerberosTicketRetriever.java:188) Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7) - LOOKING_UP_SERVER) at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:710) at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248) at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179) at KerberosTicketRetriever$TicketCreatorAction.createTicket(KerberosTicketRetriever.java:105) at KerberosTicketRetriever$TicketCreatorAction.run(KerberosTicketRetriever.java:72) ... 4 more Caused by: KrbException: Server not found in Kerberos database (7) - LOOKING_UP_SERVER at sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:73) at sun.security.krb5.KrbTgsReq.getReply(KrbTgsReq.java:192) at sun.security.krb5.KrbTgsReq.sendAndGetCreds(KrbTgsReq.java:203) at sun.security.krb5.internal.CredentialsUtil.serviceCreds(CredentialsUtil.java:311) at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(CredentialsUtil.java:115) at sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:442) at sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:641) ... 8 more Caused by: KrbException: Identifier doesn't match expected value (906) at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143) at sun.security.krb5.internal.TGSRep.init(TGSRep.java:66) at sun.security.krb5.internal.TGSRep.<init>(TGSRep.java:61) at sun.security.krb5.KrbTgsRep.<init>(KrbTgsRep.java:55) ... 14 more Disconnected from the target VM, address: '127.0.0.1:51126', transport: 'socket' Process finished with exit code 1 

And my java code:

 import com.sun.security.auth.callback.DialogCallbackHandler; import org.ietf.jgss.*; import sun.misc.BASE64Encoder; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import java.io.*; import java.security.Principal; import java.security.PrivilegedAction; import java.util.Set; /** * Tool to retrieve a kerberos ticket. This one will not be stored in the windows ticket cache. */ public final class KerberosTicketRetriever { private final static Oid KERB_V5_OID; private final static Oid KRB5_PRINCIPAL_NAME_OID; static { try { KERB_V5_OID = new Oid("1.2.840.113554.1.2.2"); KRB5_PRINCIPAL_NAME_OID = new Oid("1.2.840.113554.1.2.2.1"); } catch (final GSSException ex) { throw new Error(ex); } } /** * Not to be instanciated */ private KerberosTicketRetriever() {}; /** * */ private static class TicketCreatorAction implements PrivilegedAction { final String userPrincipal; final String applicationPrincipal; private StringBuffer outputBuffer; /** * * @param userPrincipal p.ex. <tt> MuelleHA@MYFIRM.COM </tt> * @param applicationPrincipal p.ex. <tt>HTTP/webserver.myfirm.com</tt> */ private TicketCreatorAction(final String userPrincipal, final String applicationPrincipal) { this.userPrincipal = userPrincipal; this.applicationPrincipal = applicationPrincipal; } private void setOutputBuffer(final StringBuffer newOutputBuffer) { outputBuffer = newOutputBuffer; } /** * Only calls {@link #createTicket()} * @return <tt>null</tt> */ public Object run() { try { createTicket(); } catch (final GSSException ex) { throw new Error(ex); } return null; } /** * * @throws GSSException */ private void createTicket () throws GSSException { final GSSManager manager = GSSManager.getInstance(); final GSSName clientName = manager.createName(userPrincipal, KRB5_PRINCIPAL_NAME_OID); final GSSCredential clientCred = manager.createCredential(clientName, 8 * 3600, KERB_V5_OID, GSSCredential.INITIATE_ONLY); final GSSName serverName = manager.createName(applicationPrincipal, KRB5_PRINCIPAL_NAME_OID); final GSSContext context = manager.createContext(serverName, KERB_V5_OID, clientCred, GSSContext.DEFAULT_LIFETIME); context.requestMutualAuth(true); context.requestConf(false); context.requestInteg(true); final byte[] outToken = context.initSecContext(new byte[0], 0, 0); if (outputBuffer !=null) { outputBuffer.append(String.format("Src Name: %s\n", context.getSrcName())); outputBuffer.append(String.format("Target : %s\n", context.getTargName())); outputBuffer.append(new BASE64Encoder().encode(outToken)); outputBuffer.append("\n"); } context.dispose(); } } /** * * @param realm p.ex. <tt>MYFIRM.COM</tt> * @param kdc p.ex. <tt>kerbserver.myfirm.com</tt> * @param applicationPrincipal cf. {@link #TicketCreatorAction(String, String)} * @throws GSSException * @throws LoginException */ static public String retrieveTicket( final String realm, final String kdc, final String applicationPrincipal) throws GSSException, LoginException { // create the jass-config-file final File jaasConfFile; try { jaasConfFile = File.createTempFile("jaas.conf", null); final PrintStream bos = new PrintStream(new FileOutputStream(jaasConfFile)); bos.print(String.format( "Krb5LoginContext { com.sun.security.auth.module.Krb5LoginModule required refreshKrb5Config=true useTicketCache=true debug=true ; };" )); bos.close(); jaasConfFile.deleteOnExit(); } catch (final IOException ex) { throw new IOError(ex); } // set the properties System.setProperty("java.security.krb5.realm", realm); System.setProperty("java.security.krb5.kdc", kdc); System.setProperty("java.security.auth.login.config",jaasConfFile.getAbsolutePath()); // get the Subject(), ie the current user under Windows final Subject subject = new Subject(); final LoginContext lc = new LoginContext("Krb5LoginContext", subject, new DialogCallbackHandler()); try { lc.login(); } catch (LoginException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. //e = Client not found in Kerberos database (6) - CLIENT_NOT_FOUND System.exit(0); } // extract our principal final Set<Principal> principalSet = subject.getPrincipals(); if (principalSet.size() != 1) throw new AssertionError("No or several principals: " + principalSet); final Principal userPrincipal = principalSet.iterator().next(); // now try to execute the SampleAction as the authenticated Subject // action.run() without doAsPrivileged leads to // No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt) final TicketCreatorAction action = new TicketCreatorAction(userPrincipal.getName(), applicationPrincipal); final StringBuffer outputBuffer = new StringBuffer(); action.setOutputBuffer(outputBuffer); Subject.doAsPrivileged(lc.getSubject(), action, null); return outputBuffer.toString(); } public static void main (final String args[]) throws Throwable { final String ticket = retrieveTicket("EXAMPLE.COM", "EXAMPLE.COM", "HTTP/webserver.myfirm.com"); System.out.println(ticket); } } 
+7
source share
1 answer

I did not test your code, but read stacktrace. I believe the problem is with the KDC domain. As the documentation says :

the default scope and KDC for this scope are specified in Kerberos krb5.conf

Usually the KDC area in krb5.conf is kdc . Example from a default fedora installation:

 [realms] EXAMPLE.COM = { kdc = kerberos.example.com admin_server = kerberos.example.com } 

It seems obvious that you should change your kdc domain to a domain name, not a domain name:

 final String ticket = retrieveTicket("EXAMPLE.COM", "localhost", "HTTP/webserver.myfirm.com"); 

You are using Kerberos on the local computer, you can add the dns_lookup_kdc = false option to your krb5.conf

+2
source

All Articles