Security: Tomcat 5.5.20, Sun AS9UR1, Sun AM7.1
By ajitsabnis on Dec 02, 2006
A simple web-app to understand JEE security concepts is attached. It shows:
- Principal name from HttpServletRequest.getUserPrincipal()
- Name from HttpServletRequest.getRemoteUser()
- Whether the user belongs to role specified as "role" request parameter
Lets say we've two users: user1, admin1.
user1 belongs to roles/groups: user, authenticated, testuser.
admin1 belongs to roles/groups: admin, authenticated, testadmin.
Note that web.xml uses security-role-ref to control access to ControllerServlet. This has significance w.r.t. how Tomcat 5.5.20 behaves versus how Sun AS 9UR1 behaves as
- Tomcat 5.5.20 uses tomcat-users.xml to define roles. Once user
logs in, say using FORM based authentication, then even if
security-role-ref/security-role is not used or referred in web.xml, the
on HttpServletRequest work as if security-role-ref/security-role is
used in web.xml.
This is probably not JEE compliant. But, it has some advantages as
we'll see below. There is no concept of realm in Tomcat 5.5.20,
probably for its not JEE 5 compliant.
- Sun AS 9 UR1 is JEE5-compliant, and uses realms, and supports pluggable authentication and authorization modules (JSRs 115, 196, part of JEE5 I believe). The three calls mentioned above don't work as expected if we don't define security-role-ref/security-role in web.xml for ControllerServlet! This is spec compliant probably, but restrictive as well for unless you refer a role in web.xml, you cannot use it as parameter to isUserInRole() call even though the identity may belong to the role-name.
Sun AS way allows only role-names mentioned in web.xml returning true if passed to isUserInRole(). That is even if a user belongs to certain group (with Default Principal to Role Mapping turned on on AS9UR1 AdminConsole), isUserInRole returns false for that group if not mentioned as security-role-ref role-name in web.xml!
What this means is from composite applications (many web-apps participating in serving one request):
- On Tomcat 5.5.20, as long as user is authenticated (has an identity), any web-app can use isUserInRole() to pass role-name that can be configured in different way per web-app. For example, one web-app may use web.xml to refer the security-role, others may derive isUserInRole() parameter from properties file. Or, all of them refer on properties file. If you have lots of web-apps, you (the deployer) don't need to mess around with web.xmls at deploy time.
- On SunAS9.1UR1, its not possible to do this! Probably
spec-compliance is secondary to how easy it is for deployers to use the
system. I hope this is a bug that can be fixed easily rather than
conceptual mis-understanding or wrong design. :-)
OK, please try out the example to validate above understanding. Probably, I didn't capture it correctly. Or, I might have mis-understood something.
SunAM7.1 is not a JACC Provider, i.e. it doesn't fit with JEE5 pluggable authentication, authorization mechanism. That is, you have to use JEE/J2EE Policy Agent product from AM team to make the above 3 "programmatic" security APIs of HttpServletRequest (and respective EJB security APIs) to work. That means,
- You need to configure the J2EE Policy Agent for your
WebContainer. Please see here and here for SunAS9
- You need to edit your web-app.xml to add Agent Filters so that you get correct HttpServletRequest wrapper in place to make the 3 APIs work for you!
- You need to edit sun-web.xml of your (WebServices) web-app to add
httpservlet-security-provider="AMHttpProvider" attribute to the root
element. And, so on as Aravind mentions in his blog entry here.
Oh, missed to mention...It's really cool to have NetBeans 5.5 Enterprise Pack. It has SunAS9.1UR1 and SunAM7.1 to play around with.