Every now and then I get an assignment that includes an application that should use Kerberos authentication for access to a resource of some sort. One of the first things I like to try out is to use the program below to see that I have got the correct credentials and that the resource is up and running. Because I rarely work with this I thought it would be best to put the code and instructions here:
1. First we create a krb5.conf file with the settings for the domain in question. There are a few ways to do this but I usually use the following way:
>kinit <user name> #Creates an entry in the auth table for that user >klist #Displays all entrys in auth table. Credentials cache: C:\Users\niklas\krb5cc_niklas Default principal: niklas@MYDOMAIN.SE, 1 entry found. [1] Service Principal: krbtgt/MYDOMAIN.SE@MYDOMAIN.SE Valid starting: Jun 09, 2023 10:12:50 Expires: Jun 09, 2023 20:12:50
We can here see the domain to use: MYDOMAIN.SE. This will be used in the [realms] section of the krb5.conf file
Now we need the DNS/IP for a KDC to put in the [libdefaults] section
>nslookup -type=srv _kerberos._tcp.MYDOMAIN.SE Server: dns1.mydomain.se Address: 192.168.10.1 _kerberos._tcp.MYDOMAIN.SE SRV service location: priority = 0 weight = 100 port = 88 svr hostname = kdc0093.mydomain.se _kerberos._tcp.MYDOMAIN.SE SRV service location: priority = 0 weight = 100 port = 88 svr hostname = kdc0094.mydomain.se _kerberos._tcp.MYDOMAIN.SE SRV service location: priority = 0 weight = 100 port = 88 svr hostname = kdc0099.mydomain.se
Here we can pick one and fill the krb5.conf file like below:
[libdefaults] default_realm = MYDOMAIN.SE [realms] VGREGION.SE = { kdc = kdc0093.mydomain.se }
After this we also need a login.conf with some settings needed for the demo program
2. Login.conf
com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false useTicketCache=true; };
3. Now it is time for the program
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.net.URL; public class RunHttpKerberos { static final String kuser = "admin"; // Username static final String kpass = "admin"; // Password static final String kurl = "https://resource.mydomain.se/data" static class MyAuthenticator extends Authenticator { public PasswordAuthentication getPasswordAuthentication() { return (new PasswordAuthentication(kuser, kpass.toCharArray())); } } public static void main(String[] args) throws Exception { Authenticator.setDefault(new MyAuthenticator()); URL url = new URL(kurl); InputStream ins = url.openConnection().getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); String str; while((str = reader.readLine()) != null) System.out.println(str); } }
4. Compile and run the program with the following arguments
java -Djava.security.krb5.conf=krb5.conf -Djava.security.auth.login.config=login.conf -Djavax.security.auth.useSubjectCredsOnly=false RunHttpKerberos
For DEBUG logging slap on a “-Dsun.security.krb5.debug=true”
If auth works you should see the resource printed in console
Tested om Java 1.8.0_352 and Windows 10