Tomcat-Jaas - How to retrieve subject?

sasaman85 picture sasaman85 · Oct 25, 2012 · Viewed 9.8k times · Source

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?

Answer

Arjan Tijms picture Arjan Tijms · Nov 11, 2012

i knew that and it works, but I need to retrieve subject to get also roleprincipal

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):

The JAAS Specification describes the result of a successful login as a javax.security.auth.Subject instance, which can contain zero or more java.security.Principal objects in the return value of the Subject.getPrincipals() method. However, it provides no guidance on how to distinguish Principals that describe the individual user (and are thus appropriate to return as the value of request.getUserPrincipal() in a web application) from the Principal(s) that describe the authorized roles for this user. To maintain as much independence as possible from the underlying LoginMethod implementation executed by JAAS, the following policy is implemented by this Realm: [...]

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, then HttpServletRequest#getUserPrincipal() might return a org.jboss.security.SimplePrincipal. The only thing guaranteed is that getName() 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;

Although it is possible to use JAAS within Tomcat as an authentication mechanism (JAASRealm), the flexibility of the JAAS framework is lost once the user is authenticated. This is because the principals are used to denote the concepts of "user" and "role", and are no longer available in the security context in which the webapp is executed. The result of the authentication is available only through request.getRemoteUser() and request.isUserInRole().

This reduces the JAAS framework for authorization purposes to a simple user/role system that loses its connection with the Java Security Policy.