Andy Pemberton Rotating Header Image

Securing AJAX Servlets in JBoss Portal

Before the Portlet 2 specification (JSR286), the recommended method for adding AJAX functionality to a JSR168 portlet was to deploy an additional servlet to the portal server (either inside the same WAR as your portlet(s) or in a stand-alone WAR) to handle asynchronous requests. Requests to these servlets are then handled by the servlet container as opposed to being routed through the portlet container, so they don’t automatically inherit the security context from the portal, as your portlets would.

The goal of this article is to describe how to enable security in your AJAX servlets in JBoss Portal 2.6.

JBoss Portal 2.7 supports JSR286, which has features built into portlets for serving AJAX requests. So while this technique may be less useful in that environment, nothing precludes the use of AJAX servlets in the 286 environment, so this technique may still come in handy.

Securing AJAX servlets in JBoss Portal 2.6 involves four high-level steps.

Step 1: Add the Portal’s Security Application Policy to the Servlet Container

Step 1 is mostly a copy/paste effort. The key point here is that you’re configuring the servlet container to use the same JAAS settings that you’ve configured the Portal to use. You’ll want to look at the Portal’s JAAS settings in: $PS_HOME/server/default/deploy/jboss-portal.sar/conf/login-config.xml

There should be a block that looks something like: - you’ll want to copy this block into the login-config used by the servlet container at: $PS_HOME/server/default/conf/login-config.xml


<application-policy name="portal">
	<authentication>
		<login-module code="org.jboss.portal.identity.auth.IdentityLoginModule" flag="required">
			<module-option name="unauthenticatedIdentity">guest</module-option>
			<module-option name="userModuleJNDIName">java:/portal/UserModule</module-option>
			<module-option name="roleModuleJNDIName">java:/portal/RoleModule</module-option>
			<module-option name="userProfileModuleJNDIName">java:/portal/UserProfileModule</module-option>
			<module-option name="membershipModuleJNDIName">java:/portal/MembershipModule</module-option>
			<module-option name="additionalRole">Authenticated</module-option>
			<module-option name="password-stacking">useFirstPass</module-option>
		</login-module>
	</authentication>
</application-policy>

Step 2: Secure your AJAX Servlet Web Application

This step is standard for securing web applications; just add the appropriate security settings to the web.xml deployed with your AJAX servlet WAR.

For example, these settings may look like:


<security-constraint>
	<web-resource-collection>
		<web-resource-name>Security</web-resource-name>
		<url-pattern>/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>Authenticated</role-name>
	</auth-constraint>
</security-constraint>
<login-config>
	<auth-method>BASIC</auth-method>
	<realm-name>JBoss Portal</realm-name>
</login-config>
<security-role>
	<role-name>Authenticated</role-name>
</security-role>

Step 3: Configure your Servlet Web App to use the Portal Security Policy

At this point, we need to tell the servlet web app which JAAS security-domain to use, ie: the one we added in step 1. To do this, JBoss has a proprietary extension to the servlet spec that uses a file: jboss-web.xml in the same location as your web.xml. Add in the following:


<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 4.2//EN"
    "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">
<jboss-web>
	<security-domain>java:jaas/portal</security-domain>
</jboss-web>

At this point, your servlet web application should be secured and using the same security-domain as the Portal. There’s only one small problem: when you first log in you’ll notice (if you used BASIC as your auth-method as in my example), you’ll get prompted to login from your AJAX calls in addition to logging in to the portal. This is because the Portal and your AJAX servlet application are separate web applications deployed to the application server, and do not inherently trust eachother’s authenticated sessions.

Step 4: Enable Single Sign On between the Portal and your Servlet Web App

Luckily, JBoss uses Tomcat under the covers as the servlet container, and Tomcat has a nice, out-of-the-box feature for enabling single-sign-on (SSO) between web apps. To do so, you simply need to enable the SSO valve in Tomcat’s server configuration at: $PS_HOME/server/default/deploy/jboss-web.deployer/server.xml

See the Portal reference guide for more information on enabling SSO in Tomcat.

Conclusion

So that does it. Your AJAX servlets are now secured using the same security-domain as your Portal install and are configured for SSO.

Hopefully you found this technique helpful; if you have any comments, questions, or improvements please comment.

5 Comments on “Securing AJAX Servlets in JBoss Portal”

  1. #1 Matt Comer
    on Jan 16th, 2009 at 11:01 am

    Nice write-up Andy. ;<)

  2. #2 Stephen Houston
    on Sep 14th, 2009 at 6:41 pm

    Thanks Andy, this was a great help!

    Just a note on this. It doesn’t work (in Portal 2.7 at least) if you use the

    org.jboss.web.tomcat.security.ExtendedSingleSignOn

    value to support programmatic sign on. However switching to

    org.jboss.web.tomcat.service.sso.ClusteredSingleSignOn

    works with both the authentication challenge (above) and the programmatic sign on.

    The only other thing I did differently was using FORM rather than BASIC auth.

  3. #3 Andy Pemberton
    on Sep 14th, 2009 at 7:00 pm

    @Stephen:

    Very cool; glad this was helpful. In my scenario, I actually disabled authentication altogether (by removing the login-config element from web.xml).

    This way, users can only authenticate from our primary login screen; AJAX calls simply return a 401 that our AJAX framework handles with a modal dialog letting the user know they’ve timed-out.

  4. #4 Daniel Kuschow
    on Jan 20th, 2010 at 12:25 pm

    Wonderful stuff. But one problem i ran into, if a user try to logout. Only in Portal user will be logged out. But if i call an AJAX-URL after logging out, the webapp session is still valid. So after this call - thanks to SSO - the user can also retrieve portal pages again without the need to relog :(

    If you have a clue, how to “really” logout a user, I would be very grateful.

  5. #5 Daniel Kuschow
    on Jan 20th, 2010 at 12:57 pm

    Sorry for spam, but your tip with removing the login-config element works like a charm. Thanks a lot for this wonderful documentation.

Leave a Comment