Java Authentication and Authorization Service aka JAAS is a pretty neat way to build a pluggable authentication mechanism for a Java application.
My goal was to build a Single Sign-on (SSO) mechanism targeted on Windows machines (Windows XP SP3, Windows 7) that uses the cached kerberos ticket.
The jaas configuration should be pretty simple:
name_of_the_login_context { com.sun.security.auth.module.Krb5LoginModule required debug=true doNotPrompt=true useTicketCache=true renewTGT=true ; };
This means: Require and use the Krb5LoginModule module, do not prompt for a user details and use the windows ticket cache. As it turns out, this works out of the box with Java 6 but does not with Java 7.
Java 7 respects a Windows feature that disables the export of Sessions Key for Ticket-Granting Tickets so the native TGT on Windows (XP with SP2, Vista and 7) has an empty session key.
To enable the export of non empty Session keys add the following registry setting on Vista, 7 and Server:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters Value Name: AllowTgtSessionKey Value Type: REG_DWORD Value: 0x01 ( default is 0 )
and this on XP SP2
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\ Value Name: AllowTgtSessionKey Value Type: REG_DWORD Value: 0x01
I expected the configuration to work… But it didn’t. It seems there are problems with User Account Control (UAC) and domain users that are local admins (so is my account on my machine). I tried to disable UAC (not acceptable for either me or the customer), adding the setting above to the KDC server, creating a krb5.ini file and some other attempts but no success. The jaas configuration started to work as soon as i removed my account from the local admins. Funny thing is: I readded it and it still works.
While doing my research i found several other irritating behaviors:
As SSO wasn’t working, it tried the following JAAS config:
name_of_the_login_context { com.sun.security.auth.module.Krb5LoginModule required debug=true useTicketCache=false ; };
This should force a login prompt with an adequate javax.security.auth.callback.CallbackHandler. On my Windows 7 machine Java 6 *does* need a krb5.ini file under c:\windows, Java 7 does not.
The exception with Java 6 is: “KrbException: Could not load configuration file C:\Windows\krb5.ini”
So i created one… After that, i had a “KrbException: Message stream modified (41)”, great, thanks. The problem here is the case sensitivity of the realm name. If the domain is FOOBAR and the krb5.ini contains
[realms] foobar = { kdc = dc.foobar admin_server = dc.foobar default_domain = foobar }
the authentication will fail. If the kdc returns the realm as FOOBAR, the krb5.ini must contain the realm FOOBAR like so
[realms] FOOBAR = { kdc = dc.foobar admin_server = dc.foobar default_domain = foobar }
Seems to be fun for the whole family… Hopefully this will save someone else some hours of frustration.
tl;dr
- Java 6 on Windows 7 needs a krb5.ini file when useTicketCache == false
- The realm name in krb5.ini is case sensitive
- Kerberos SSO under Windows works only with AllowTgtSessionKey set to 1 under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
- Kerberos SSO doesn’t work reliable with Domain Users that are local machine admins due to UAC
Update on the location of the jaas.conf file
I was asked how and where to specifiy the location of the JAAS configuration file. You basically have 3 options (for Java 7).
- The JRE looks for a default jaas.conf in
“file:${user.home}/.java.login.config” - You can add configuration files to java.security located in “lib/security” in the JRE base directory like so:
“login.config.url.1=file:C:/config/.java.login.config” - Or you can specify the jaas configuration on the command line with:
“-Djava.security.auth.login.config=path_to_file”
4 comments
The shortcommings of pure Java Kerberos interopability with Windows is also discussed here:
http://stackoverflow.com/quest.....in-windows
http://bugs.java.com/bugdataba.....id=6722928
Apparently if the patch named in the Stackoverflow question would be applied all would work well in standard JDK. But that doesn’t seem to be happening. Also I’ve recently learned that the Apache HttpClient have implemented Kerberos support on Windows platform using SSPI (as opposed to standard JDK classes, e.g. HttpUrlConnection) so they do not have all the issues that that standard JDK classes have.
If you want to get rid of krb5.ini, you can set a couple of system properties in your code, instead. For me, the lines of code were:
System.setProperty(“java.security.krb5.realm”, realm);
System.setProperty(“java.security.krb5.kdc”, kdc);
Hi Michael,
even though your post is 5 years old, it still saved the day for me today 🙂
Using Java 8 on Windows 7, I could not get SSO to work.
After removing my domain account from local admins, it worked like a charm!
However, contrary to your experience, after re-adding it, it ceased to work.
Nevertheless, Thanks a lot!!
Hi,
thanks a lot for your feedback.
Yeah, that topic is still a major PITA.
Post a Comment