I'm studying JAAS and I'm implementing a simple example to use in a webapp using Tomcat with a JaasRealm.
Now my problem is that I don't know how to retrieve the subject since code like Subject subject = Subject.getSubject(AccessController.getContext());
always returns null.
I'm using Tomcat 7.0.27. Is there something I've missed? In other terms how can I manage authorization in Java EE with JAAS? For example how can I implement an action within the secure context of JAAS?
Unfortunately, it doesn't work like that in Java EE. The JAAS Subject is just a "bag of principals", and which of those represents the user/caller principal and/or the role principal(s) is simply not standardized. Every other container does things differently here. The Javadoc for Tomcat's JAASRealm describes this and explains the Tomcat specific convention (emphasis mine):
Besides that, from a Java EE environment you rarely even have access to the JAAS Subject, often not even via vendor specific methods. JAAS is far from the universal standard that you seem to think it is, especially when it concerns Java EE.
The only things which you can access in a portable way are the caller principal and the roles associated with it, but even those do not have to be the exact caller principal that your JAAS login module constructed.
JBoss AS for instance, copies this principal a couple of times using its own classes. So, if your JAAS module stored a
kaz.zak.FooPrincipal
into the Subject for the user/caller principal, thenHttpServletRequest#getUserPrincipal()
might return aorg.jboss.security.SimplePrincipal
. The only thing guaranteed is thatgetName()
on that instance will return the same string.For some more background on this topic:
The last source basically says the same thing, in different wording;
To retrieve Subject we can use the combination of LoginModule and Valve. The fact that valves are invoked before authentication kicks in is helping us here. When the valve is invoked it puts the session in ThreadLocal (similar to how JBOSS saves request in ThreadLocal) and later when LoginModule.commit() is invoked it saves the subject into the session.
To configure this add compiled code for class below to a jar and place it under $CATALINA_BASE/lib/
In $CATALINA_BASE/conf/server.xml add following Valve configuration as element's child.
In jaas.config file add the same class as LoginModule.
Now after you login, authenticated Subject can be retrieved using following.