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.
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.