New security APIs in WebSphere Portal

This article gives a detailed introduction, usage scenarios, guidelines, and samples to three new security APIs: the portlet login service, the remember me cookie portlet service, and the authentication filter model. The portlet login service, available since IBM® WebSphere® Portal V6.0.1, allows triggering of a login by username and password from a portlet. The remember me cookie portlet service enables you to use the new remember me cookie functionality introduced with WebSphere Portal V6.1 from your portlet. Third, the authentication filter model provides six plug-points to add custom code to the WebSphere Portal login, logout, and session handling flows.

Share:

Jan-Paul Buchwald (JPBUCH@de.ibm.com), WebSphere Portal Security Team, IBM, Software Group

Jan-Paul Buchwald is an IT Specialist in the IBM Development Laboratory in Boeblingen, Germany. He received a Diploma of Computer Science at the Albert Einstein University of Ulm, Germany. After gaining experience for several years as a software engineer working on the development of WebSphere Portal, Jan-Paul joined the WebSphere Portal Lab Services Team in 2008. You can reach him at JPBUCH@de.ibm.com.



Matthias Falkenberg (MFALKENB@de.ibm.com), IT Consultant, IBM

Matthias Falkenberg is an IT Consultant in the IBM Development Laboratory in Boeblingen, Germany. He received a Diploma of Business Computing from the University of Applied Sciences Wildau, Germany, and joined the Lab-based Services Team for WebSphere Portal in 2007. Since then Matthias has worked in development for WebSphere Portal in the fields of security and Web content management and performs customer engagements related to WebSphere Portal. You can reach him at MFALKENB@de.ibm.com.



29 June 2009 (First published 27 May 2009)

Editor's note: Know a lot about this topic? Want to share your expertise? Participate in the IBM Lotus software wiki program today.

Introduction

Although WebSphere Portal provides many ways to configure a variety of security scenarios, it is often necessary to customize or extend the default product capabilities for login, logout, or session handling. In recent versions, several public APIs have been introduced in the security layer of WebSphere Portal.

This article introduces the three new security APIs step by step and provides a code sample that is extended incrementally. First, the login portlet service is described as it is available in WebSphere Portal V6.0.1. Afterward the focus shifts to new APIs with WebSphere Portal V6.1, starting with the extension of the login portlet service and the remember me cookie portlet service. Finally, the authentication filter plug-points are described in detail.


Login Portlet Service

There are several scenarios and use cases:

  • The public login portlet service introduced with WebSphere Portal V6.0.1 (interface com.ibm.portal.portlet.service.login.LoginService) can be used to trigger a form-based login to WebSphere Portal from any portlet (see the developerWorks® article “Understanding and Configuring WebSphere Portal login and logout” [1] for more information about the overall login flow – the portlet service triggers the same flow as the out-of-the-box login portlet). This service is useful in a couple of different scenarios in which the following conditions apply: It is necessary to enhance the login portlet by additional elements, for example, a custom form, additional input elements, or enhanced portlet functionality.
  • The user input or parts of it need to be modified by some logic before being passed to the actual login.
  • You want to propagate information from the user interface to the actual login, for example, in the javax.security.auth.Subject object passed on to the Java™ Authentication and Authorization Service (JAAS) login or the login context that is passed to the ExplicitLoginFilter elements introduced with WebSphere Portal V6.1. (See the description of the explicit login in the section, "Authentication filters").
  • You want to influence the login portlet’s behavior in reaction to particular errors that might occur during the login, for example, a redirect operation to a dedicated page to change the password after the login failed, indicating that the password expired.

Detailed description of the interface

An instance of the com.ibm.portal.portlet.service.login.LoginService is retrieved for a particular portlet request and response pair using the com.ibm.portal.portlet.service.login.LoginHome interface, which can be looked up using Java Naming and Directory Interface (JNDI) once (for example, during portlet initialization). In the 6.0.1 version, the service provides one method to trigger a login that takes the user ID, password, a mandatory java.util.Map object that holds context information, and an optional prefilled javax.security.auth.Subject object.

The login method defines a couple of exceptions to distinguish several error conditions that can cause the login to fail and might be handled appropriately in the portlet. Additionally, the interface defines a constant DO_RESUME_SESSION_KEY to be used as a key to store a java.lang.Boolean object to indicate whether the portal should perform a session resume (if WebSphere Portal session persistence is enabled, see the WebSphere Portal Information Center on session persistence on login or not. Listing 1 shows how to retrieve the service and trigger a default login without specifying any context information or passing on a prefilled subject.

Listing 1. Usage of portlet login service
1.	import java.util.*;
2.	import javax.portlet.*;
3.	import javax.naming.Context;
4.	import javax.naming.InitialContext;
5.	import javax.naming.NamingException;
6.	import com.ibm.portal.portlet.service.PortletServiceHome;
7.	import com.ibm.portal.portlet.service.login.LoginHome;
8.	import com.ibm.portal.portlet.service.login.LoginService;
9.	
10.	// initialize the service home (should be done once during init) 
11.	try { 
12.	  PortletServiceHome psh;
13.	  Context ctx = new InitialContext();
14.	  psh = (PortletServiceHome) ctx.lookup(LoginHome.JNDI_NAME);
15.	  LoginHome loginHome = (LoginHome) psh.getPortletService(LoginHome.class);
16.	} catch (NamingException ex) {
17.	  throw new PortletException("Service not available", ex);
18.	}
19.	
20.	// retrieve and use the login service (in the processAction method) 
21.	String userid = request.getParameter("userid");
22.	String password = request.getParameter("password");
23.	LoginService loginService = 
		(LoginService) loginHome.getLoginService(request, response); 
24.	
25.	try {
26.	  loginService.login(userid, password.toCharArray(), Collections.EMPTY_MAP, null);
27.	} catch (…) {
28.	// Error handling
29.	}
30.	// Portal will trigger a redirect if the login succeeded

Sample part 1

The first part of the sample scenario shows an example for a custom login portlet that uses the login portlet service as defined for WebSphere Portal V6.0.1. The input form for the login takes an additional personnel number and stores this value in a com.ibm.portal.example.PersonnelPrincipal object that is added to the principals of a new javax.security.auth.Subject object. This subject is then passed to the login triggered with the portlet login service. The JAAS login module com.ibm.portal.example.PersonnelLoginModule reads the personnel number information from the subject and verifies its accuracy. For simplicity, the sample code verifies only that the personnel number is set and rejects all personnel numbers that start with the digit 1.

If an error occurs during login, the portlet renders the view with the login form again, additionally displaying the message of the error on the top.


Capabilities of the remember me cookie

The remember me feature allows Web applications to identify users who previously logged in using any means of authentication, for example, a combination of username and password or a client certificate. To realize this user identification, a manually performed authentication is not required; instead an HTTP cookie holds the claim of identity. This remember me cookie is persisted in the client’s Web browser upon an initial successful login. If the user returns to the Web application later and the Web browser sends along the cookie, the user is recognized automatically. With WebSphere Portal V6.1, this feature eventually found its way into portal technology as an capability that is ready to use without modification.

Scenarios and use cases

Most of the use cases involving a remember me cookie belong to the wide field of personalization. Based on the user profile that is retrievable after a user has been identified, the previously anonymous public portal area can be transformed into an individual-centric starting point for navigating the portal site. To users the portal site can be much more appealing than it has ever been.

Thereby, the opportunities go beyond a personal greeting on a welcome page: The language of the portal site can be switched to the user’s preferred language instantly upon the first access, or a password retrieval function could employ the email address stored in the user profile. Moreover, information presented to the user can depend on the user’s interests or department affiliation.

Extensions to the login portlet service

As described earlier, the public login portlet service lets you implement custom login portlets that on their part trigger the user login to WebSphere Portal. In WebSphere Portal V6.1, additions to this service take the new remember me cookie capabilities into account. In particular, two constants have been added to the interface com.ibm.portal.portlet.service.login.LoginService:

  • DO_SET_REMEMBER_ME_COOKIE to indicate whether a remember me cookie is issued for the requesting user if the login is successful
  • DO_DELETE_REMEMBER_ME_COOKIE to indicate whether the remember me cookie is revoked for the requesting user if the login is successful

Both DO_SET_REMEMBER_ME_COOKIE and DO_DELETE_REMEMBER_ME_COOKIE are to be used as keys to store a java.lang.Boolean object in the portal login context map that is passed into the login method of the login portlet service. These context parameters are optional, and the default behavior of the default portal login logic is not to perform any action; that is, the remember me cookie is neither set nor revoked. Furthermore, the evaluation of these parameters assumes the activation of the remember me feature (see also the WebSphere Portal V6.1 Information Center).

In addition, the login portlet service has been enhanced with regard to the methods it offers. The new method isFormAuthenticated indicates whether the current portal user has been authenticated using the default login mechanism of WebSphere Portal, which is a form-based authentication. Used in conjunction with step-up authentication and an automatic login based on the remember me cookie (see also the WebSphere Portal V6.1 iInformation Center), this method lets you determine whether a login portlet should still render the login form. The user might have gained access to the protected portal area because of presenting a valid remember me cookie. In this case, the login form should still be rendered to allow the user to reach the higher authentication level linked to form-based authentication.

Using the Puma Service in a public context

Starting with WebSphere Portal V6.1, the com.ibm.portal.um.PumaProfile interface allows retrieval of a com.ibm.portal.um.User object representing the current user and querying the current user’s profile attributes in public context. The only assumption made here is that a remember me cookie is available to identify the requesting user. A user profile can be obtained by calling the getPumaProfile method exposed by the PumaHome interfaces. In total, there are three of these interfaces, each one of them serving a different purpose:

  • com.ibm.portal.um.portletservice.PumaHome for JSR 168 and JSR 286 portlets
  • com.ibm.portal.um.portletservice.legacy.PumaHome for legacy IBM portlets
  • com.ibm.portal.um.PumaHome for other application code not related to portlet programming, for example, custom session validation filter implementations

The code snippet shown in listing 2 illustrates how the current user and the user’s preferred language can be retrieved by a JSR compliant portlet.

Listing 2. Retrieve user attributes with the PUMA service
1.	import com.ibm.portal.portlet.service.PortletServiceHome;
2.	import com.ibm.portal.um.PumaProfile;
3.	import com.ibm.portal.um.User;
4.	import com.ibm.portal.um.exceptions.PumaException; 
5.	import com.ibm.portal.um.portletservice.PumaHome;
6.	
7.	public class PumaProfileSamplePortlet extends GenericPortlet 
8.	{
9.	// Home interface of the PumaHome service
10.	private PortletServiceHome m_pumaHome = null;
11.	
12.	  // Name of the user attribute holding the user's preferred language
13.	  final static String ATTR_PREF_LANG = "preferredLanguage";
14.	
15.	  // Initialize the list of user attributes to query
16.	  static 
17.	  {
18.	    List<String> attrNames = new ArrayList<String>(1); 
19.	    attrNames.add(ATTR_PREF_LANG); 
20.	  }
21.	
22.	  public void init(PortletConfig portletConfig) throws UnavailableException, 
		  PortletException 
23.	  {
24.	    super.init(portletConfig); 
25.	
26.	    try 
27.	    {
28.	      javax.naming.Context ctx = new javax.naming.InitialContext();
29.	      m_pumaHome = (PortletServiceHome) ctx.lookup
			  ("portletservice/com.ibm.portal.um.portletservice.PumaHome");
30.	    } 
31.	    catch (NamingException e) 
32.	    {
33.	      getPortletContext().log("Lookup of portletservice/com.ibm.portal.um.
			  portletservice.PumaHome failed.", e); 
34.	      throw new PortletException("Initialization of portlet failed"); 
35.	    }
36.	  } // End init()
37.	
38.	  protected void doView(RenderRequest req, 
		  RenderResponse resp) throws PortletException, IOException 
39.	  {
40.	
41.	    // Get the PumaProfile service from the PumaHome service
42.	    PumaHome service = (PumaHome) m_pumaHome.getPortletService(PumaHome.class); 
43.	    PumaProfile profile = service.getProfile(req); 
44.	
45.	    // Obtain the user object to work with
46.	    User currentUser = null; 
47.	    try {
48.	      currentUser = profile.getCurrentUser();
49.	    } 
50.	    catch (PumaException e) 
51.	    {
52.	      getPortletContext().log("Retrieval of current user failed.", e); 
53.	    }
54.	
55.	    String prefLang = null; 
56.	    if (currentUser != null) 
57.	    {
58.	      // Get the user's preferred language using the PumaProfile
59.	      try 
60.	      {
61.	        Map attrMap = profile.getAttributes(currentUser, attributeNames); 
62.	        prefLang = attrMap.get(ATTR_PREF_LANG); 
63.	      } 
64.	      catch (Exception e) 
65.	      {
66.	        getPortletContext().log("Retrieval of the user's preferred language failed.", e); 
67.	      }
68.	    }
69.	
70.	    // Generate markup
71.	
72.	  } // End doView()73.	}

While the provided code can be used in portlets deployed to WebSphere Portal regardless of the activation of the remember me service, it returns only the user’s preferred language on public WebSphere Portal pages if the functionality is enabled and if a valid remember me cookie is encapsulated in the request. That is to say, if the remember me function is disabled or if the remember me cookie is not present, the current user object as returned by the PumaHome service is null and user attributes cannot be fetched.

Remember me cookie portlet service

Apart from accessing the user profile of identified but still unauthenticated users in a public context, it is desirable to allow the user to revoke the remember me cookie. This is where the com.ibm.portal.portletservice.rememberme.RememberMeCookieService API comes into play. This service is made available in WebSphere Portal V6.1 to JSR 168 or JSR 286 portlets. After a service object has been acquired, the following methods are available:

  • isRememberMeCookieEnabled. Checks whether the remember me function is enabled and whether the initialization was successful.
  • isCookieSet. Checks whether a remember me cookie is present in the current request.
  • getUserID. Retrieves the ID of the user to which the remember me cookie belongs.
  • getInvalidateCookieURL. Generates a URL to revoke the remember me cookie.

The code snippet shown in listing 3 exemplifies how the RememberMeCookieService API can be employed in portlet code.

Listing 3. Usage of remember me cookie service
1.	import java.io.StringWriter; 
2.	import com.ibm.portal.portlet.service.PortletServiceHome; 
3.	import com.ibm.portal.portletservice.rememberme.RememberMe cookieService; 
4.	
5.	public class RememberMeSamplePortlet extends GenericPortlet 
6.	{
7.	  // Home interface of the RememberMe cookieService
8.	  private static PortletServiceHome m_rmcHome = null; 
9.	
10.	  public void init(PortletConfig portletConfig) throws UnavailableException, 
		  PortletException 
11.	  {
12.	    super.init(portletConfig); 
13.	
14.	    try 
15.	    {
16.	      javax.naming.Context ctx = new javax.naming.InitialContext();
17.	      m_pumaHome = 
			  (PortletServiceHome) ctx.lookup(RememberMe cookieService.JNDI_NAME); 
18.	    } 
19.	    catch (NamingException e) 
20.	    {
21.	      getPortletContext().log("Lookup of " + 
			  RememberMe cookieService.JNDI_NAME + " failed.", e); 
22.	      throw new PortletException("Initialization of portlet failed"); 
23.	    }
24.	  } // End init
25.	
26.	  protected void doView(RenderRequest req, RenderResponse resp) 
		  throws PortletException, IOException 
27.	  {
28.	    // use the remember me cookie service
29.	    RememberMe cookieService rmcService = (RememberMe cookieService) 
			m_rmcHome.getPortletService(RememberMe cookieService.class); 
30.	
31.	    String rmcRevocationURL = null; 
32.	    // Check whether remember me is enabled, otherwise we will 
33.	    // risk an OperationNotSupportedException
34.	    if rmcService.isRememberMe cookieEnabled())
35.	    {
36.	      try 
37.	      {
38.	        StringWriter writer = new StringWriter();
39.	        rmcService.getInvalidateCookieURL(req, resp).writeDispose(writer); 
40.	        rmcRevocationURL = writer.toString();
41.	      } 
42.	      catch (Exception e) 
43.	      {
44.	        getPortletContext().log("Generation of the URL to invalidate the 
				remember me cookie failed.", e); 
45.	      }
46.	    }
47.	
48.	    // Generate markup
49.	
50.	  } // End doView()51.	}

The sample code demonstrates how the RememberMeCookieService home interface is looked up using JNDI in the init method of the portlet. When the portlet is rendered in VIEW mode, the doView method first verifies that the remember me feature is enabled in the WebSphere Portal setup. This step should always be done prior to calling any other service methods because this verification would result in an javax.naming.OperationNotSupportedException being thrown in case the service is not available.

Afterward, the service method getInvalidateCookieURL is called to get hold of a com.ibm.portal.state.DisposableURL object that is immediately serialized as a java.lang.String. This string could then be written to the portlet markup. The common use case here would be to render a hyperlink offering to the user to invalidate the cookie that stores the user’s identity.

Sample part 2

The second part of the sample extends the login portlet developed in the first part to support the new capabilities provided with WebSphere Portal V6.1. The portlet now additionally uses the remember me cookie portlet service to check whether the remember me cookie function is enabled. If that is the case, the portlet displays an additional checkbox that allows the user to control whether the cookie is set upon login. If the portlet is able to retrieve the user identity from an existing cookie, it also greets this user and provides the link to a URL to invalidate the remember me cookie.

Another portlet, the Sample Request Form portlet, supplements the second part of the sample. It implements a form allowing users to send requests to the portal support, for example, to unlock a user ID or to reset a password. For simplicity, successful requests are written only to the log file of WebSphere Portal while the user is directed to a summary of the request. The special characteristic of this portlet is that it distinguishes between unknown users, users that are identified by a remember me cookie, and users that are logged on to the portal.

In a public context, this portlet requires the employment of the remember me cookie portlet service to display a personalized message and to render a link to revoke the cookie.

Moreover, the portlet completes the presented form automatically with the user attribute values it retrieves from the PumaProfile service. Because of leveraging the remember me cookie capabilities of WebSphere Portal V6.1, the portlet also prefills the request form for unauthenticated users, provided that a remember me cookie is provided.


Authentication filters

WebSphere Portal V6.1 introduces a public API called Authentication Filters (also see the WebSphere Portal V6.1 Information Center for more information on this topic[3]) that can be used to plug into the portal login, logout, session timeout handling, and request validation. The API is supposed to replace the login and logout command plug-points that are not a public API, but only documented in a technote. These plug-points still exist in WebSphere Portal V6.1, but it is recommended that you move existing customizations to the new API.

Migrating existing custom code to the new API

According to the diagrams of the flow of actions on WebSphere Portal login mentioned in the previous article about WebSphere Portal login, the filter chains for the explicit login (triggered by login portlet or login URL) and implicit login (login in WebSphere Portal when being already authenticated in the IBM WebSphere Application Server) embed in the overall sequence as shown in figures 1 and 2.

Figure 1. Flow for the explicit login in WebSphere Portal V6.1
Flow for the explicit login in WebSphere Portal V6.1
Figure 2. Flow for the implicit login in WebSphere Portal V6.1
Flow for the implicit login in WebSphere Portal V6.1

The filter chains replace the former LoginUser command, which is still supported but should no longer be used. The WebSphere Portal default filters now trigger the necessary logic for the WebSphere Portal login itself. For the implicit login, there is no longer a redirect operation unless the property redirect.login.authenticated.url of the WP ConfigService is set or a custom filter explicitly sets a redirect target.

Detailed description of the authentication filter chains

In the following tables, the six filter chains are discussed in detail. For each use case, first the Java interface is referenced. Then the points of invocations and the overall flow are described. Finally, some examples of usage scenarios and, where it makes sense, implementation comments are given for each kind of filter.

Table 1. Explicit login
Interfacecom.ibm.portal.auth.ExplicitLoginFilter
Points of invocationLogin by user ID and password either using the login portlet service (which is also used by the default login portlet) or the login URL.
Description of overall flow In case of a successful login, a redirect operation is triggered directly after the filter chain has been processed completely. If there are exceptions during the login, these are either passed to the login portlet service or, when using the login URL, the portal gives an HTTP error.
Usage scenarios
  • Perform additional operations before the portal login (for example, a check if a user has accepted the terms of conditions), with the option not to trigger the next element in the chain to quit the login
  • Set dynamic redirect targets after successful login
  • Perform additional operations after the portal login (for example, logging)
  • Catch and handle or transform exceptions thrown by the portal login or subsequent filters
Table 2. Implicit login
Interfacecom.ibm.portal.auth.ImplicitLoginFilter
Points of invocationAt the beginning of WebSphere Portal request processing, before calling the preprocessors, handling the actions, and rendering the page, when the user already has received a security context by the WebSphere Application Server, but is not yet logged in to WebSphere Portal.
Description of overall flow In case of a successful WebSphere Portal login, the request processing continues using the correct portal user context of the user that has been just logged in. A redirect operation is triggered only if the property redirect.login.authenticated.url of the WP ConfigService is set or a custom filter explicitly sets a redirect URL. If there are exceptions during the login, the portal gives an HTTP error.
Usage scenarios
  • Perform additional operations before or after the implicit portal login (for example, to check particular conditions, set additional context information or provide custom logging).
  • Set dynamic redirect targets after successful login.
Implementation commentsInside a filter for the implicit login, the user to be logged in can be retrieved using the PUMA API without context information (com.ibm.portal.um.PumaHome.getProfile()).

To quit the implicit login, implementations must throw an exception, it is not sufficient not to call the next element in the filter chain.
Table 3. Explicit logout
Interfacecom.ibm.portal.auth.ExplicitLogoutFilter
Points of invocationLogout of WebSphere Portal triggered by the user when clicking the logout link or a link to invalidate the remember me cookie (if WebSphere Portal is configured to log in the user based on the remember me cookie).
Description of overall flow In case of a successful logout, a redirect operation is triggered directly after the filter chain has been processed completely. If there are exceptions during the logout, the portal gives an HTTP error.
Usage scenarios
  • Perform additional operations before or after the portal logout (for example, cleanup effort or logging)
  • Set dynamic redirect targets after successful logout
Implementation commentsInside a filter for the explicit logout, the user to be logged out can be retrieved using the PUMA API without context information (com.ibm.portal.um.PumaHome.getProfile()). This retrieval should be done before calling the next element in the chain, as the WebSphere Portal default logout filter invalidates the security context.

To quit the explicit logout, implementations must throw an exception; it is not sufficient not to call the next element in the filter chain.
Table 4. Implicit logout
Interfacecom.ibm.portal.auth.ImplicitLogoutFilter
Points of invocation
  • When a user is logged out in the first request after having received a session timeout in WebSphere Portal, if the WebSphere Application Server security session is still valid. This scenario is the default behavior if the property timeout.resume.session in the WP ConfigService is not set to true.
  • When a user is logged out because of accessing a public WebSphere Portal page. This is the default behavior if the property uri.home.substitution in the WP ConfigService is not set to true.
  • When a user is logged out because of accessing a virtual portal without being member of the associated user realm.
Description of overall flow In case of a successful logout, a redirect operation is triggered directly after the filter chain has been processed completely (see the developerWorks article about WebSphere Portal login for the details on the default redirect targets for the different use cases). If there are exceptions during the logout, the portal gives an HTTP error.
Usage scenarios
  • Perform additional operations before or after the implicit portal logout (for example, cleanup effort or logging)
  • Set dynamic redirect targets after successful implicit logout
Implementation commentsInside a filter for the implicit logout, the user to be logged out can be retrieved using the PUMA API without context information (com.ibm.portal.um.PumaHome.getProfile()). This retrieval should be done before calling the next element in the chain, as the WebSphere Portal default logout filter invalidates the security context.

To quit the implicit logout, implementations must throw an exception; it is not sufficient not to call the next element in the filter chain.

Session timeout

NOTE: This filter relates only to the timeout of the overall WebSphere Portal session. To perform additional operations when particular portlet sessions time out or are invalidated for other reasons, implement a javax.servlet.http.HttpSessionListener and register it in the web.xml of the portlet application according to the Java Platform, Enterprise Edition (Java EE) specification.

Table 5. Session timeout
Interfacecom.ibm.portal.auth.SessionTimeoutFilter
Points of invocationWhen the event for the idle timeout of the WebSphere Portal session is received
Description of overall flow The session timeout filters are called after the default WebSphere Portal session timeout handling has been performed.
Usage scenarios Additional operations on the WebSphere Portal session timeout (for example, logging, persisting state, and so on).
Implementation commentsAs this filter provides no request or response context, the user whose session has timed out cannot be retrieved using the PUMA API. If the custom code handling the session timeout is supposed to operate on the user object, the latter can be stored as a session attribute earlier, for example, by a custom login filter.
Table 6. Session validation
Interfacecom.ibm.portal.auth.SessionValidationFilter
Points of invocationFor each WebSphere Portal request (including JSR 286 resource requests), before actions are triggered or the rendering is performed.

If a redirect operation is set by a preprocessor or the implicit login or logout, the session validation is not performed before the redirect operation. For the explicit login or logout, the session validation is performed before the respective login or logout filters.
Description of overall flow If a redirect operation is set when the session validation filter chain completes successfully, this operation is executed immediately, quitting the rest of the WebSphere Portal request processing. If an exception is thrown by one of the filters, the portal gives an HTTP error.
Usage scenarios Additional operations that need to be performed upon each WebSphere Portal request (for example, continuous checks, logging, and so on).
Implementation commentsThis hook point is also used by the step-up authentication capability in WebSphere Portal. If you plan to combine custom session validation filters with step-up authentication, the filter implementations should be clear about the consequences of particular operations (especially the cases of not calling the next element in the chain and overwriting redirect URLs set by the default filter).

Migrating existing custom code to the new API

Existing code for customizing the WebSphere Portal login or logout based on the commands described in a technote can, in most cases, be easily moved to the new API.

Table 7 provides some help on how the old plug-points map to the new ones.

Table 7: Mapping of old and new plug-point elements
Old customizationWith the new API
LoginUser.doPreLogin with user ID and password arguments set to actual values ExplicitLoginFilter before calling the next element in the chain
LoginUser.doPreLogin with user ID and password arguments both set to nullImplicitLoginFilter before calling the next element in the chain
LoginUser.doPostLogin with user ID and password arguments set to actual values ExplicitLoginFilter after the next element in the chain has returned
LoginUser.doPostLogin with user ID and password arguments both set to null ImplicitLoginFilter after the next element in the chain has returned
LogoutUser.doPreLogoutExplicitLogoutFilter or ImplicitLogoutFilter before calling the next element in the chain
LogoutUser.doPostLogoutExplicitLogoutFilter or ImplicitLogoutFilter after the next element in the chain has returned
LogoutUser.onUserSessionTimeoutSessionTimeoutFilter before or after the next element in the chain

Instead of using the com.ibm.wps.engine.RunData object, the new API provides the HTTP servlet request and response objects of the current WebSphere Portal request directly.

Sample part 3

The third part of the sample realizes several filters for different use cases:

  • A filter for the explicit login stores the current user object to the session and sets dynamic redirect URLs based on the department affiliation of the user. The mapping of departments to redirect URLs is part of the filter configuration and can be set for each department by specifying the property filterchain.properties.com.ibm.example.portal.SampleLoginFilter.<department name>=<redirect URL> in the resource environment provider AuthenticationService of WebSphere Portal. Additionally, the login filter stores the current user to the session, which is needed to use the custom session timeout filter.
  • A filter for the explicit logout sets dynamic redirect URLs based on the department affiliation. The mapping of departments to redirect URLs is part of the filter configuration and can be set for each department by specifying the property filterchain.properties.com.ibm.example.portal.SampleLogoutFilter.<department name>=<redirect URL> in the AuthenticationService of WebSphere Portal.
  • A session timeout filter reads the user object from the session (where it has been put by the login filter) and stores a flag as an attribute value for the user to indicate that the user did receive a session timeout.

This part of the sample also includes the portlet entitled Sample Timeout Received Warning, which reads the session timeout user attribute set by the sample session timeout filter. If the user received a session timeout, a warning message is displayed upon next login to remind the user to always log out properly. This portlet then offers a link to remove the message and reset the session timeout user attribute using the PUMA API.


How to compile and use the sample code

Required configuration for parts 2 and 3 of the sample

To enable the remember me cookie feature on WebSphere Portal V6.1, follow the instructions in the "Enabling step-up authentication or the remember me cookie" section in the Information Center according to your operating system.

The authentication filters make use of two user attributes, department of type String and timeout of type Boolean. If these attributes do not exist in your user repository, add them as new attributes as appropriate to your user repository configuration. Several alternatives exist to add custom user attributes to a WebSphere Portal environment. On one hand, if the configured user repository does not permit attribute modifications, configure a property extension database to store the user attributes from the sample. Refer to the chapter "Configuring a property extension database on <Operating System>" in the Information Center according to your operating system.

If the user registry allows adding the user attributes department and timeout, add the attributes to the WebSphere Portal configuration as well. The necessary steps are described in the "Managing Attributes" section in the Information Center with regard to various operating systems.

Compiling and installing the samples

The sample code is packaged into several Eclipse projects. As the first part of the sample is supposed to run on WebSphere Portal V6.0.1 and later, it has to be compiled with Java 1.4.2. Therefore, the two projects SampleLoginModule and SampleLoginPortlet_601 should be imported into an Eclipse workspace using a 1.4.2 JVM. The other projects refer to WebSphere Portal V6.1 and should be compiled using Java 5.

As Eclipse is not aware of the WebSphere Portal runtime, the appropriate WebSphere Application Server and WebSphere Portal libraries need to be attached manually to the build path. The following overview lists the prerequisite libraries for each project and describes how to build and use the resulting deliverable.

  • SampleLoginModule

    Uses only core Java prerequisites.

    Export the project as a JAR file and place it in the WebSphere Application Server classpath (for example, to <Application Server root directory>/lib/ext).

    Add the login module com.ibm.example.portal.PersonnelLoginModule to the JAAS configuration Portal_LTPA.

    These instructions apply to both WebSphere Portal V6.0.1 and later and WebSphere Portal V6.1.

  • SampleLoginPortlet_601

    Add the following external libraries (from a WebSphere Portal V6.0.1 and later installation) to the build path of the project:

    • sas.jar from the <Application Server root directory>/lib directory
    • wp.base.jar, wp.auth.base.jar, jsr-168-api.jar, and wp.pe.api.standard.jar from the <Portal Server root directory>/shared/app directory

    Export the project as a Web archive (WAR file) that can be deployed as a portlet.

    Install the portlet to WebSphere Portal, give the anonymous user permissions to use the portlet, and place it on the welcome or login page (it can be deployed in addition to the original login portlet).

  • SampleLoginPortlet_61

    Add the following external libraries (from a WebSphere Portal V6.1 installation) to the build path of the project:

    • com.ibm.ws.runtime_6.1.0.jar and com.ibm.ws.portletcontainer_6.1.0.jar from the <WebSphere Application Server root directory>/plugins directory
    • wp.base.jar from <WebSphere Portal root directory>/base/wp.base/shared/app
    • wp.auth.base.jar from <WebSphere Portal root directory>/base/wp.auth.base/shared/app
    • wp.pe.api.standard.jar from <WebSphere Portal root directory>/base/wp.pe.api.standard.jar/shared/app
    • wp.model.api.jar from <WebSphere Portal root directory>/base/wp.model.api/shared/app
    • wp.portletservices.api.standard.jar from <WebSphere Portal root directory>/base/wp.portletservices.api/shared/app
    • wp.user.api.jar from <WebSphere Portal root directory>/base/wp.user.api/shared/app

    Export the project as a Web archive (WAR file) that can be deployed as a portlet.

    Install the portlet to WebSphere Portal, give the anonymous user permissions to use the portlet, and place it on the welcome or login page (it can be deployed in addition to the original login portlet).

  • SampleRequestFormPortlet

    Add the following external libraries (from a WebSphere Portal V6.1 installation) to the build path of the project:

    • com.ibm.ws.runtime_6.1.0.jar and com.ibm.ws.portletcontainer_6.1.0.jar from the >Application Server root directory>/plugins directory
    • wp.base.jar from <WebSphere Portal root directory>/base/wp.base/shared/app
    • wp.auth.base.jar from <WebSphere Portal root directory>/base/wp.auth.base/shared/app
    • wp.pe.api.standard.jar from <WebSphere Portal root directory>/base/wp.pe.api.standard.jar/shared/app
    • wp.model.api.jar from <WebSphere Portal root directory>/base/wp.model.api/shared/app
    • wp.portletservices.api.standard.jar from >WebSphere Portal root directory>/base/wp.portletservices.api/shared/app
    • wp.user.api.jar from <WebSphere Portal root directory>/base/wp.user.api/shared/app

    Export the project as a Web archive (WAR file) that can be deployed as a portlet.

    Install the portlet to WebSphere Portal, give all the authenticated portal users and the anonymous user permissions to use the portlet, and place it on a new WebSphere Portal page that can be accessed by all authenticated portal users and anonymous users.

  • SampleFilters

    Add the following external libraries (from a WebSphere Portal V6.1 installation) to the build path of the project:

    • com.ibm.ws.runtime_6.1.0.jar and com.ibm.ws.webcontainer_2.0.0.jar from the <WebSphere Application Server root directory>/plugins directory
    • j2ee.jar from the <WebSphere Application Server root directory>/lib
    • wp.base.jar from the <WebSphere Portal root directory>/base/wp.base/shared/app
    • wp.auth.base.jar from the <WebSphere Portal root directory>/base/wp.auth.base/shared/app
    • wp.user.api.jar from the <WebSphere Portal root directory>/base/wp.user.api/shared/app

    Export the project as a JAR file and place it in the WebSphere Portal class path (for example, <WebSphere Portal root directory>/shared/app).

    Set the following properties in the WP AuthenticationService resource environment provider and restart WebSphere Portal:

    login.explicit.filterchain = com.ibm.example.portal.SampleLoginFilter
    filterchain.properties.com.ibm.example.portal.SampleLoginFilter.1234 = >some URL<
    logout.explicit.filterchain = com.ibm.example.portal.SampleLogoutFilter
    filterchain.properties.com.ibm.example.portal.SampleLogoutFilter.1234 = >some URL>
    sessiontimeout.filterchain = com.ibm.example.portal.SampleSessionTimeoutFilter
  • SampleTimeoutReceivedWarningPortlet

    Add the following external libraries (from a WebSphere Portal V6.1 installation) to the build path of the project:

    • com.ibm.ws.portletcontainer_6.1.0.jar from the >WebSphere Application Server root directory>/plugins directory
    • wp.base.jar from the <WebSphere Portal root directory>/base/wp.base/shared/app
    • wp.auth.base.jar from the <WebSphere Portal root directory>/base/wp.auth.base/shared/app
    • wp.pe.api.standard.jar from the <WebSphere Portal root directory>/base/wp.pe.api.standard.jar/shared/app
    • wp.model.api.jar from the <WebSphere Portal root directory>/base/wp.model.api/shared/app
    • wp.portletservices.api.standard.jar from the <WebSphere Portal root directory>/base/wp.portletservices.api/shared/app
    • wp.user.api.jar from the <WebSphere Portal root directory>/base/wp.user.api/shared/app

    Export the project as a Web archive (WAR file) that can be deployed as a portlet.

    Install the portlet to WebSphere Portal, give all authenticated portal users permission to use the portlet, place it at the top of the Getting Started page and at the top of the redirect target pages for each department of the sample, and assign the NoSkin as skin used to render the portlet in the WebSphere Portal user interface.

    Export the project as a Web archive (WAR file) that can be deployed as a portlet.

Verifying the sample

If you have successfully completed all the previously described steps, the sample scenario should look like the following:

  • In the WebSphere Portal V6.0.1 or later part, the sample login portlet accepts the personnel number in an additional text field, and the login is rejected if no personnel number or a personnel number starting with the digit 1 is entered.
  • In the WebSphere Portal V6.1 part, the sample login portlet offers a check box to indicate whether users want to be remembered by the portal. If the browser already sends the remember me cookie, the respective user is greeted and a link is provided to revoke that cookie. After a successful login and logout, the user is redirected depending on the configured URL according to the user’s department affiliation. See figure 3.

    Figure 3. Screen capture of the sample login portlet
    Screen capture of the sample login portlet
  • In the WebSphere Portal V6.1 part, the SampleRequestFormPortlet shows available attribute values in the public portal area if the browser sends the remember me cookie.
  • In the WebSphere Portal V6.1 part, the Getting Started page (or each page on which you placed the SampleTimeoutReceivedWarningPortlet) shows an additional warning if the user received a session timeout in a previous session as shown in figure 4.

    Figure 4. Screen capture of the SampleTimeoutReceivedWarningPortlet
    Screen capture of the SampleTimeoutReceivedWarningPortlet

Conclusion

With version 6.0.1, the openness of WebSphere Portal in regards to user login customizations was brought forward with the introduction of the public login portlet service. As the sample provided with this article demonstrates, custom login portlets can employ this service to trigger a form-based user login to WebSphere Portal.

Starting with WebSphere Portal V6.1, more sophisticated authentication and session handling scenarios can be realized as a filter chain API named Authentication Filters has been made publicly available. Filter implementations can be plugged into the WebSphere Portal login, logout, request validation, and session timeout flow; hence, a new level of customizations of the WebSphere Portal security processing is available. At the same time, this filter infrastructure replaces customizations to login or logout based on commands that had been published in a technote for earlier WebSphere Portal versions.

The sample comprises several custom authentication filters. It is complemented by a demonstration of the capabilities of the public API that leverages the remember me capability, combining state-of-the-art user identification techniques with portal technology. The public login portlet service and the public Puma API have been extended to allow for this new function in WebSphere Portal V6.1. Additionally, the remember me cookie portlet service, whose usage is exemplified in the sample, provides further access to functions related to this particular feature.


Downloads

DescriptionNameSize
Code sampleSampleCode_601.zip9.27KB
Code sampleSampleCode_61.zip34KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=391921
ArticleTitle=New security APIs in WebSphere Portal
publish-date=06292009