This post is a bit of an experiment, rather than like most of my posts where I come up with an idea and document it once complete I am going to blog about my progress getting this to work as I go, a sort of impressionist blog, which is most likely the way they were originally intended to be done.
What is SSO?
The way I see single sign on, which may not be the right way to view it, is that a user in a company has to interact with a multitude of computer systems, each of which requires some form of authentication before access is granted and single sign on means that a user once authenticated in one system will auto-magically be authenticated in the others without being prompted for a username and password or whatever.
The first method that I am looking at is Kerberos, the way I think this works is that a user signs in using whatever means at their disposal (card reader, password or biometric scanner) then that user has a token that is given to any other systems that require authentication.
The premise here is that there is a single secure token provider that every application within the enterprise/corporation then trusts.
JAAS the java way
Being a Java developer on enterprise systems I would have been lucky to have not had to have some experience with using JAAS the java authentication authorisation service. This is a pluggable system like much of the JEE components where any particular vendor can make their own implementation, and as luck would have it there is already a Kerberos version available.
JBoss
I am going to use JBoss (likely version 4 but maybe 7 as I kinda like where that's going) as my application server, I may show using GlassFish too, plus I may also show it being used in tomcat just for kicks.
Step 1
In order to actually test these things out I need to actually have a kerberos system setup, as I tend to use Linux the instructions for setting this up will be linux orientated.
I followed these instructions for installing and setting up a kerberos system.
I rapidly hit a stumbling block with the first pre-requisite of the installation
Before installing the Kerberos server a properly configured DNS server is needed for your domainD'oh! I don't have a DNS server, so I went to get one and set it up. Doing a quick google I found these instructions which are for Ubuntu and as I am using a Debian system thought it would work. I didn't bother following any of the reverse DNS lookup instructions as (a) I am lazy and (b) I want to move on quickly from setting up a dns. The only thing to note at this point is that nslookup gw didn't give any results.
Back to installing Kerberos
So now that dns seems to be installed time to go back to the kerberos instructions.
Everytime I try kinit steve/admin I get
kinit: Cannot resolve network address for KDC in realm "RLJASSOCIATES" while getting initial credentials
I altered the instructions for both dns installation and kerberos installation so that the domain is RLJASSOCIATES.
I found a forum that states;
"each host's IP address must reverse-resolve the canonical name."so I guess it's time to go back to the DNS setup instructions once more, damn it serves me right for being lazy in the first place!
Ok the DNS setup doesn't work right off the bat but I did find a nice little utility to test called named-checkzone which I can use to check the zone files for correctness. Needless to say they weren't. Well I've been over those DNS instructions many times now so I can be absolutely sure my setup matches and guess what...they don't work so I guess they're crap!
I think there might have been a missing entry in the RLJASSOCIATES.db file so I added these lines
ns IN A 192.168.1.34
@ IN NS ns.RLJASSOCIATES
and that seems to allow nslookup gw to work.
however running sudo kinit steve/admin still results in the error
kinit: Cannot resolve network address for KDC in realm "RLJASSOCIATES" while getting initial credentialsSetting up krb5.conf
I remembered that after the first fault with the kerberos setup I uninstalled it, then when I re-installed it I was never asked the same questions about default domains once the installation was complete, this may have been the route cause of this last failure.
Essentially there is a file called /etc/krb5.conf that seems to list settings that are relevant for different domains, so I took a guess at what to write and put this in;
RLJASSOCIATES = {I have no idea if this is correct or not apart from when I ran this command kinit steve/admin instead of it failing with the usual error message shown above it prompted for the password, which I typed in and ... nothing happened which still means no error :)
kdc = rjohnson-acer.RLJASSOCIATES
admin_server = rjohnson-acer.RLJASSOCIATES
default_domain = RLJASSOCIATES
}
The next fault to get over in the kerberos instructions is
#> kinit steve@RLJASSOCIATESOnce again I have no idea what is causing this to happen, so on to professor google.
kinit: Client not found in Kerberos database while getting initial credentials
Not actually sure this is an error as the list of principals is now
kadmin: list_principals
K/M@RLJASSOCIATESThe big issue is that it says I am not entering the correct password for kadmin/admin and yet I know damn well what I entered so this might be an issue with the re-installation I tried earlier ooops!
kadmin/admin@RLJASSOCIATES
kadmin/changepw@RLJASSOCIATES
kadmin/history@RLJASSOCIATES
kadmin/rjohnson-acer@RLJASSOCIATES
krbtgt/RLJASSOCIATES@RLJASSOCIATES
steve/admin@RLJASSOCIATES
JBoss
I am going to start with a vanilla installation of jboss-4.2.3.GA, simply because I wanted to start with a version 4 and this was the latest 4 I found on jboss community site, don't worry I'll show the same kerberos stuff on jboss-7.0.2, I would want to use 7.1.0 as this is the version where remote ejb calls are supported but it doesn't exist yet tee hee :)
The current setup for security on this app is;
<authentication>
<login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
<module-option name="usersProperties">props/jmx-console-users.properties</module-option>
<module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
</login-module>
</authentication>
</application-policy>
So in order to use the same login that I want to use for kerberos I've created a user called steve and I've added that to the props/jmx-console-users.properties.
So I changed the login-config.xml to read
<application-policy name="jmx-console">
<authentication>
<login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required">
<module-option name="debug">true</module-option>
</login-module>
</authentication>
</application-policy>
Hooray
It looks like I was successful, the usual prompt popped up so I logged in as Steve and hey presto got this in the log
10:38:00,978 INFO [STDOUT] Acquire TGT using AS Exchange
10:38:01,056 INFO [STDOUT] principal is steve@RLJASSOCIATES
10:38:01,057 INFO [STDOUT] EncryptionKey: keyType=3 keyBytes (hex dump)=0000: FE 75 E3 7A 1A 29 7C A8
10:38:01,057 INFO [STDOUT] EncryptionKey: keyType=1 keyBytes (hex dump)=0000: FE 75 E3 7A 1A 29 7C A8
10:38:01,057 INFO [STDOUT] EncryptionKey: keyType=23 keyBytes (hex dump)=0000: 3D 8C CB 99 50 CC 9A 13 69 12 6D AA BF E7 C6 4E =...P...i.m....N
10:38:01,058 INFO [STDOUT] EncryptionKey: keyType=16 keyBytes (hex dump)=0000: 79 75 9B A7 67 EC BF 2F 7A 32 C1 C8 9E AB 57 0D yu..g../z2....W.
0010: 5B B3 3D D0 64 F4 34 4F
10:38:01,058 INFO [STDOUT] EncryptionKey: keyType=17 keyBytes (hex dump)=0000: 87 17 D5 4C 61 35 48 4D D4 8B 14 58 91 E5 E8 AE ...La5HM...X....
10:38:01,078 INFO [STDOUT] Commit Succeeded
Actually do SSO
- a way of automatically sending a username to do the login, this wouldn't just be a username but would need to be the TGT.
- a way to set the Subject to the user signing in, currently we only have the principal.
Done...I think
Not sure if this is done now but it seems to be which is strange as I've set virtually nothing up?
login-config.xml
<application-policy name="jmx-console">
<authentication>
<login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required">
<module-option name="debug">true</module-option>
<module-option name="useTicketCache">true</module-option>
<module-option name="doNotPrompt">false</module-option>
<module-option name="useKeyTab">true</module-option>
<module-option name="useKeyTab">true</module-option>
</login-module>
</authentication>
</application-policy>
But is it SSO
The simple truth is I don't know at the moment I haven't tested it and this is because I am not sure how to test it, so lets look back at square 1 what was the criteria;
- not be able to access resource (/jmx-console) if I am not authenticated.
- authenticate via the KDC.
- once authenticated don't get prompted for authentication again.
One More Piece of the puzzle
I've not had much time to look into all of this stuff at the moment and tidy up this rambling blog post, this link looks like it'll be quite useful.
http://download.oracle.com/javase/1.4.2/docs/guide/security/jgss/single-signon.html
http://download.oracle.com/javase/1.5.0/docs/guide/security/jgss/tutorials/JGSSvsJSSE.html
http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html