Showing posts with label loginfilters. Show all posts
Showing posts with label loginfilters. Show all posts

SessionTimeoutFilter, for executing some logic when your portal session is timedout

If you want to execute some logic when user session times out Ex, some cleanup logic that you want to call when user logs out, then you can implement SessionTimeoutFilter. This filter is called immediately after the session of a user has been destroyed either by an idle timeout or by an invalidation of the session (e.g. due to a mismatch of session and request user). It is not called when the user is logged out properly.

I wanted to try this feature so i did create a simple SessionTimeoutFilter that will print out name of the user who's session is getting timed out. Note that you dont get access to HttpServletRequest object so you will have to pass that name as HttpSession attribute, set it using LoginFilter and then read the name in the SessionTimeoutFilter


package com.webspherenotes.auth;

import java.util.Map;

import javax.servlet.http.HttpSession;

import com.ibm.portal.auth.SessionTimeoutFilter;
import com.ibm.portal.auth.SessionTimeoutFilterChain;
import com.ibm.portal.auth.exceptions.UserSessionTimeoutException;
import com.ibm.portal.security.SecurityFilterConfig;
import com.ibm.portal.security.exceptions.SecurityFilterInitException;

public class SampleSessionTimeoutFilter implements SessionTimeoutFilter{
public void destroy() {
}

public void init(SecurityFilterConfig arg0)
throws SecurityFilterInitException {
}
public void onUserSessionTimeout(HttpSession session, Map map,
SessionTimeoutFilterChain filterChain) throws UserSessionTimeoutException {
System.out.println("Inside SampleSessionTimeoutFilter.onUserSessionTimeout SessionId "
+ session.getId());
System.out.println("Inside SampleSessionTimeoutFilter.onUserSessionTimeout, User Name "
+ session.getAttribute("userName"));
filterChain.onUserSessionTimeout(session, map);
}
}

Use SessionValidationFilter for executing logic before every page

The SessionValidationFilter allows you to execute business logic before action is requested and page is rendered. This method will get executed once for every page. You can use this method to redirect user to different page, generate some debugging information. Ex. lets say you have a requirement that every time a page gets rendered you will have to check if the page is empty(no portlets), if yes redirect user to different page.

I did create this SampleSessionValidationFilter that prints out the request and session information for the portal before every request.


package com.webspherenotes.auth;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.ibm.portal.auth.FilterChainContext;
import com.ibm.portal.auth.SessionValidationFilter;
import com.ibm.portal.auth.SessionValidationFilterChain;
import com.ibm.portal.auth.exceptions.SessionValidationException;
import com.ibm.portal.security.SecurityFilterConfig;
import com.ibm.portal.security.exceptions.SecurityFilterInitException;

public class SampleSessionValidationFilter implements SessionValidationFilter{

@Override
public void destroy() {

}

@Override
public void init(SecurityFilterConfig arg0)
throws SecurityFilterInitException {

}

@Override
public void validateSession(HttpServletRequest request,
HttpServletResponse response, FilterChainContext filterChainContext,
SessionValidationFilterChain filterChain)
throws SessionValidationException {
System.out.println("Inside SampleSessionValidationFilter.validateSession() User Name"
+ request.getRemoteUser());

System.out.println("Printing request attributes");
Enumeration attributeNameEnum = request.getAttributeNames();
while(attributeNameEnum.hasMoreElements()){
String attributeName = attributeNameEnum.nextElement();
System.out.println(attributeName +" " + request.getAttribute(attributeName));
}
System.out.println("Printing request parameters " + request.getParameterMap());

HttpSession session = request.getSession();
System.out.println("Printing request attributes");
Enumeration sessionAttributeNameEnum = session.getAttributeNames();
while(sessionAttributeNameEnum.hasMoreElements()){
String attributeName = sessionAttributeNameEnum.nextElement();
System.out.println(attributeName +" " + session.getAttribute(attributeName));
}

filterChain.validateSession(request, response, filterChainContext);

}
}


You will have to implement SessionValidationFilter interface and then you will get control inside validateSession method before the page gets rendered.

The class file for filter should go to the shared library of the server. Dont forget to register your validate sesion filter with by portal using WS_AuthenticationService

Use LogoutFilter to execute some logic, cleanup when user logs out

In the Creating loginfilter for WebSphere Portal document i mentioned steps for creating and configuring filter that lets you execute some code during the login process.

Similarly there could be requirement to extend the logout filter, Ex. you might want to cleanup the user related or user's session related entries from the DynaCache, if that's the case then you should create a LogoutFilter

Take a look at the SampleExplicitLogoutFilter that i created, which prints name of the user who is login out from the portal

package com.webspherenotes.auth;

import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.portal.auth.ExplicitLogoutFilter;
import com.ibm.portal.auth.FilterChainContext;
import com.ibm.portal.auth.LogoutFilterChain;
import com.ibm.portal.auth.exceptions.LogoutException;
import com.ibm.portal.security.SecurityFilterConfig;
import com.ibm.portal.security.exceptions.SecurityFilterInitException;

public class SampleExplicitLogoutFilter implements ExplicitLogoutFilter{

@Override
public void destroy() {

}

@Override
public void init(SecurityFilterConfig arg0)
throws SecurityFilterInitException {
}

@Override
public void logout(HttpServletRequest request, HttpServletResponse response,
FilterChainContext filterChainContext, LogoutFilterChain filterChain)
throws LogoutException, LoginException {
System.out.println("Inside SampleExplicitLogoutFilter.LoutoutFilter() RemoteUser"
+ request.getRemoteUser());
filterChain.logout(request, response, filterChainContext);

}

}


In order to create a LogoutFilter you will have to implement ExplicitLogoutFilter interface and then the logic that you want to execute during logout phase should go to logout() method.

The class file for filter should go to the shared library of the server. Dont forget to register your logout filter with by portal using WS_AuthenticationService

Redirecting user on login

One of the reader posted a comment, asking how do i redirect user as soon as they login based on some condition, so i changed my SampleExplicitLoginFilter like this


public class SampleExplicitLoginFilter implements ExplicitLoginFilter{

public void login(HttpServletRequest request, HttpServletResponse response,
String userId, char[] password, FilterChainContext portalLoginContext, Subject subject,
String realm, ExplicitLoginFilterChain chain) throws LoginException,
WSSecurityException, PasswordInvalidException,
UserIDInvalidException, AuthenticationFailedException,
AuthenticationException, SystemLoginException,
com.ibm.portal.auth.exceptions.LoginException {
System.out.println("Entering SamplExplicitLoginFilter.login()");

System.out.println("User Id " + userId);
System.out.println("Password " + String.valueOf(password));
System.out.println("Realm" + realm);

chain.login(request, response, userId, password, portalLoginContext, subject, realm);
if(request.getRemoteUser().equals("wasadmin"))
portalLoginContext.setRedirectURL("/wps/myportal/Administration");
System.out.println("Exiting SamplExplicitLoginFilter.login()");
}
public void destroy() {
}
public void init(SecurityFilterConfig arg0)
throws SecurityFilterInitException {
}

}


I am checking if the remote user is wasdmin if yes i am redirecting him to /wps/myportal/Administration page.

Creating loginfilter for WebSphere Portal

The portal authentication filters are a set of plug-in points. You can use them to intercept or extend the portal login, logout, session timeout, and request processing by custom code, for example to redirect users to a specific URL.

The New Security API in WebSphere Portal talks about various ways to extend the login process. I wanted to play with the LoginFilters so i followed simple steps to build this solution

First i did create SampleExplicityLoginFilter java class like this

public class SampleExplicitLoginFilter implements ExplicitLoginFilter{

public void login(HttpServletRequest request, HttpServletResponse response,
String userId, char[] password, FilterChainContext portalLoginContext, Subject subject,
String realm, ExplicitLoginFilterChain chain) throws LoginException,
WSSecurityException, PasswordInvalidException,
UserIDInvalidException, AuthenticationFailedException,
AuthenticationException, SystemLoginException,
com.ibm.portal.auth.exceptions.LoginException {
System.out.println("Entering SamplExplicitLoginFilter.login()");

System.out.println("User Id " + userId);
System.out.println("Password " + String.valueOf(password));
System.out.println("Realm" + realm);

chain.login(request, response, userId, password, portalLoginContext, subject, realm);
System.out.println("Exiting SamplExplicitLoginFilter.login()");
}
public void destroy() {
}
public void init(SecurityFilterConfig arg0)
throws SecurityFilterInitException {
}

}

This class only reads the userId and password and prints it in the System.out and lets control go to next step.

Similarly i did create a Sample Filter for each of the other interfaces and you can download the sample application from here

Then i built that project and copied it into the PortalServer/shared/app directory. I went to WAS Admin Console and configured all my sample login filters like this.



After that i had to restart my server but after restart when i tried login into portal i could see that i was able to get control in the LoginFilter and write userId and password used by user while login in to System.out like this


[12/17/09 10:52:51:198 PST] 0000002e SystemOut O Entering SamplExplicitLoginFilter.login()
[12/17/09 10:52:51:198 PST] 0000002e SystemOut O User Id wasadmin
[12/17/09 10:52:51:198 PST] 0000002e SystemOut O Password password
[12/17/09 10:52:51:198 PST] 0000002e SystemOut O Realmnull
[12/17/09 10:52:51:245 PST] 0000002e SystemOut O Exiting SamplExplicitLoginFilter.login()

Configure Login / Logout / Session Filter

In Portal 6.1, you can customize the behavior of the Portal in specific authentication situations, through the Authentication Filters. The Authentication Filters use the same pattern as defined by the J2EE servlet filter facility, and make use of filter chains

The following authentication filter chains are available for the developer:

  • Explicit login: This is a login by user name and password as represented by the interfacecom.ibm.portal.auth.ExplicitLoginFilter. For example, this can be a login by using the login portlet or the login URL.
  • Implicit login: For example, this can be when a user is already authenticated by WAS, but not yet to Portal. This is represented by the interface com.ibm.portal.auth.ImplicitLoginFilter.
  • Explicit logout: This means that the user triggers a logout action directly, for example by clicking the Logout button in the user interface, interface com.ibm.portal.auth.ExplicitLogoutFilter.
  • Implicit logout: For example, this can be after a session timeout, or if an authenticated user accesses a public page, or if the user navigates to a virtual portal without being member of the associated user realm. This is represented by the interface com.ibm.portal.auth.ImplicitLogoutFilter.
  • Session Timeout: This is called immediately after an idle timeout of the user session occurred. This is represented by the interface com.ibm.portal.auth.SessionTimeoutFilter.
  • Session Validation: This is called for every request before actions are triggered and the page is rendered. This is represented by the interface com.ibm.portal.auth.SessionValidationFilter.

  • You can configure them through the Portal configuration services. You can no longer set these properties by simply changing the property value in the properties file and restarting the portal. The configuration for each service is stored in and accessible through the IBM WebSphere Application Server administrative console.

    Use the following properties to define the custom filters in the various authentication filter chains in the portal. Each of these properties takes a comma-separated list of the fully qualified class names of the custom filter implementations.
    login.explicit.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered for an explicit login by user name and password. The classes listed in this property must implement the interface com.ibm.portal.auth.ExplicitLoginFilter.
    login.implicit.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered for an implicit login, that is if the user is already authenticated to WebSphere Application Server but has no portal session yet. The classes listed in this property must implement the interface com.ibm.portal.auth.ImplicitLoginFilter.
    logout.explicit.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered for an explicit logout. The classes listed in this property must implement the interface com.ibm.portal.auth.ExplicitLogoutFilter.
    logout.implicit.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered for an implicit logout, that is if the user got a session timeout. The classes listed in this property must implement the interface com.ibm.portal.auth.ImplicitLogoutFilter.
    sessiontimeout.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered directly after an idle timeout of the session occurred. The classes listed in this property must implement the interfacecom.ibm.portal.auth.SessionTimeoutFilter.
    sessionvalidation.filterchain =
    Use this property to specify the custom filters for the filter chain that is triggered for every request before the action handling and rendering is processed. The classes listed in this property must implement the interfacecom.ibm.portal.auth.SessionValidationFilter.
    filterchain.properties.. =
    Use an arbitrary set of properties according to the above pattern to specify properties for any of your custom filters. The property value is then available to the specified filter class in the SecurityFilterConfig object passed to its init method.