This documentation provides an example of integrating Jetspeed 1.6 with an application server's container managed security. In particular, with container managed user authentication. (The application server is the container).
We demonstrate how to get an authenticated user in a standard manner, via the Servlet API, and integrate those authenticated users with Jetspeed-1 Security. Our custom session validator gets the user principal from the servlet API:
//String userName = data.getRequest().getRemoteUser(); Principal principal = data.getRequest().getUserPrincipal();
and then makes this user principal available to Jetspeed and portlets running inside Jetspeed from RunData:
JetspeedUser user = rundata.getJetspeedUser();
This kind of authentication is often accomplished using the application server's authentication mechanisms, which are often based (but not always) on the JAAS (Java Authentication and Authorization Service) standard.
In this example, we integrate with the Apache Tomcat application server container. Tomcat has the concept of "realms":
For the clearest and simplest demonstration, we will integrate with Tomcat's memory realm:
MemoryRealm is a simple demonstration implementation of the Tomcat 5 Realm interface. It is not designed for production use. At startup time, MemoryRealm loads information about all users, and their corresponding roles, from an XML document (by default, this document is loaded from $CATALINA_HOME/conf/tomcat-users.xml). Changes to the data in this file are not recognized until Tomcat is restarted.
Additionally, we will integrate with roles defined in the Tomcat 5 realm. Although this example only works with Tomcat 5, the same approach can be taken with other application servers. The Jetspeed JAAS Session Validator will plugin to any Java Servlet container that implements the Servlet Spec 2.2 or higher.
The Jetspeed JAAS Session Validator plugs into the Jetspeed module architecture. It replaces the default session validator with a Servlet API-aware implementation. The default session validator gets the authenticated Jetspeed(Turbine)User from the Turbine rundata, a non-standard implementation of Java web application security.
The JAAS Session validator populates the Jetspeed User via the servlet.getUserPrincipal() call. When using this session validator, authentication is delegated to the Application Server.
To configure the JAAS session validator, we override the TurbineResources.properties and set Jetspeed's session validator in the property file found in the Jetspeed source under:
cma/WEB-INF/conf/TurbineResources.properties.merge
Here is the actual property override:
action.sessionvalidator=JAASSessionValidator
We provide an example of using Tomcat container managed authentication with Jetspeed. You can run this example directly from the Jetspeed distribution, however it requires having Tomcat 5 installed on your computer.
Required Properties:
# your app server home (tomcat) maven.war.appserver.home = /home/jetspeed/jakarta-tomcat-5.0.30
To build, simply type from the jetspeed root directory:
maven cma
The "cma" goal will build a modified version of Jetspeed 1.6 that requires logging in with Tomcat, not with Jetspeed. It also tries to deploy the jetspeed.war file directly into Tomcat using the "maven.war.appserver.home" property to locate Tomcat. When you navigate to the Jetspeed 1.6 portal from you browser, Tomcat will challenge you for a username and password. You will not be allowed to enter the portal until you type in the correct username and password. The same users and credentials are required as in the default system:
Username | Password |
---|---|
admin | jetspeed |
turbine | turbine |
JAAS Session validator populates the Jetspeed User via the servlet.getUserPrincipal() call When using this session validator, Authentication is delegated to the Application Server. Recommend disabling all user login functionality via Jetspeed, and using your web.xml to protect access to all Jetspeed resources.
In the web.xml, we place some additional security settings after resource-ref or welcome-file-list:
<security-constraint> <display-name>Jetspeed Security</display-name> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <!-- Define the context-relative URL(s) to be protected --> <url-pattern>/*</url-pattern> <!-- If you list http methods, only those methods are protected --> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint> <!-- Anyone with one of the listed roles may access this area --> <role-name>user</role-name> <role-name>admin</role-name> </auth-constraint> <!-- <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>Jetspeed BASIC Authentication</realm-name> </login-config> <!-- Default login configuration uses form-based authentication --> <!-- <login-config> <auth-method>FORM</auth-method> <realm-name>Example Form-Based Authentication Area</realm-name> <form-login-config> <form-login-page>/jsp/security/protected/login.jsp</form-login-page> <form-error-page>/jsp/security/protected/error.jsp</form-error-page> </form-login-config> </login-config> --> <!-- Security roles referenced by this web application --> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> <security-role> <role-name>guest</role-name> </security-role>
The Jetspeed application is secured in its entirety using the security constraint element of the web.xml. Here we secure the entire application with the url-pattern of "/*". The wildcard secures the entire Jetspeed webapp for all http-methods listed below. Note that we additionally add an authorization constraint on this security constraint, requiring that authenticated users also have one of the listed roles (admin or user).
<security-constraint> <display-name>Jetspeed Security</display-name> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <!-- Define the context-relative URL(s) to be protected --> <url-pattern>/*</url-pattern> <!-- If you list http methods, only those methods are protected --> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint> <!-- Anyone with one of the listed roles may access this area --> <role-name>user</role-name> <role-name>admin</role-name> </auth-constraint> </security-constraint>
In the web.xml, we also define the login method. For our example here, we define a "BASIC" HTTP authentication method often known as 'challenge' authentication. When the browser navigates to the jetspeed webapp, a dialog box is displayed asking for a username and password. Optionally, we could have also used form-based authentication as shown below in comments:
<login-config> <auth-method>BASIC</auth-method> <realm-name>Jetspeed BASIC Authentication</realm-name> </login-config> <!-- Default login configuration uses form-based authentication --> <!-- <login-config> <auth-method>FORM</auth-method> <realm-name>Example Form-Based Authentication Area</realm-name> <form-login-config> <form-login-page>/jsp/security/protected/login.jsp</form-login-page> <form-error-page>/jsp/security/protected/error.jsp</form-error-page> </form-login-config> </login-config> -->
In the web.xml, we define the required roles by this application. In our example, the roles are admin, user and guest. This is somewhat limiting, as Jetspeed 1.6 allows for the roles to be added/updated/removed at runtime.
<!-- Security roles referenced by this web application --> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> <security-role> <role-name>guest</role-name> </security-role>
Role links (references) are placed in the servlet element where the Turbine servlet is defined:
<security-role-ref> <role-name>user</role-name> <!--passed to isUserInRole()--> <role-link>user</role-link> <!--Jetspeed role name--> </security-role-ref> <security-role-ref> <role-name>admin</role-name> <role-link>admin</role-link> </security-role-ref> <security-role-ref> <role-name>guest</role-name> <role-link>guest</role-link> </security-role-ref>
You can find the complete, modified version of our web.xml in the Jetspeed source under:
cma/WEB-INF/web.xml
Lastly, for our demonstration, we add the default Jetspeed users and roles to the Tomcat Memory Realm. An example tomcat-users.xml can be found in the Jetspeed source under:
cma/tomcat-conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <!-- Tomcat Roles --> <role rolename="tomcat"/> <role rolename="manager"/> <!-- Jetspeed Roles --> <role rolename="admin"/> <role rolename="user"/> <role rolename="guest"/> <!-- Tomcat Users --> <user username="tomcat" password="tomcat" roles="tomcat"/> <!-- Jetspeed Users --> <user username="admin" password="jetspeed" roles="admin,user,manager"/> <user username="turbine" password="turbine" roles="user"/> </tomcat-users>