Tuesday, February 18, 2014

Redirecting Pentaho's Logout

At some sites, due to budget reasons, business decides to take a short cut on SSO.  Not when it comes to authentication or security which would be a big No-No, but perhaps not have a fully integrate solution with PUC.  For example...  A user logs into a portal application, and by clicking on a link they are forwarded to the Pentaho User Console (PUC).   They are automatically forwarded to the PUC home page without asking the user for additional credentials.  PUC is displayed in the separate browser tab or a popup window.  This is done through Spring Security, and SSO by passing a token to PUC and pentaho BA server validates the token by issuing a call back to a service on the portal application.

What happens when the user logs out of PUC?  The logoutFilter will call the LogoutHandlers and eventually forwards the user to the PUC’s login page.  This could create confusion to the user as they might not know how to perceive this login page?  Is this an external application?  Can they login again to PUC using their regular SSO credentials?  In this cases it is better to close the popup or the tab or perhaps forward the user back to the central portal login page.

To achieve this, it is simply a reconfiguration of the Pentaho’s BA Servers’s Spring security.  Keep in mind that Pentaho's BA Server supports Spring security 2.x (in version 5.x), and the most important configuration file that we talk about in this post is applicationContext-spring-security.xml which is located in the pentaho-solutions/system directory.

With default configuration, when a user logs out of PUC, several actions take place:
1)     On logout LogoutFilter is called as you can inspect filterChainProxy bean in applicationContext-spring-security.xml.
2)     This filter is define in a spring bean…
<bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
  <constructor-arg value="/index.jsp" >
 
  <constructor-arg>
    <list>
      <bean class="org.pentaho.platform.web.http.security.PentahoLogoutHandler" >
      <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" >
    </list>
  </constructor-arg>
  <property name="filterProcessesUrl" value="/Logout" >
</bean>
a)     The constructor is a url which points to /index.jsp which you are encouraged to discover by reading this small jsp.  But simply explained, it detected the device that the PUC is being accessed from (browser, ipad, or ipod), and adds addition information on the session or HTTP header)

b)     Additionally, the bean takes a list of LogoutHandlers:
        <bean class="org.pentaho.platform.web.http.security.PentahoLogoutHandler" >
        <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" >
… which are to be executed in order that are listed.  You can add your own Handler to do custom logic ( e.g. timestamp the logout action, or generate an event), but discourage to remove existing items.
c)     Finally, the filterProcessesUrl is a url which LogoutFilter acts on.  Normally, this will not change.

3)     Once the filter is invoked, the session is invalidated by the LogoutHandlers and the user is forwarded to /pentaho/index.jsp.
4)     Since /pentaho/index.jsp is a protected URL and requires authentication, the user is then forwarded to /pentaho/Login

This was the sequence of actions by default when a user logs out of PUC.  To close the browser, or forward the user to a different login page, we need to overwrite /index.jsp, and make sure it can be accessed by Anonymous role.  Here are the steps to achieve this:

1)     Write a simple html file and call it close.html.  It’s content can be as simple as this as what follows.  In this case, we describe the scenario of closing the browser on logout.  This file should be placed in $PENTAHenO/tomcat/webapps/pentaho directory.
<html>
<script>
window.close();
</script>
</html>

2)     Open applicationContext-spring-security.xml and modify the LogoutFilter bean
&lt;constructor-arg value="/close.html" /&gt;

3)     Also in applicationContext-spring-security.xml, modify objectDefinitionSource in filterInvocationInterceptor bean so that close.html can be accessed anonymously.  Add this line to the list of patterns:
\A/close.html\Z=Anonymous,Authenticated

Restart BA Server and test your logout function.  Keep in mind that your session was meant to be initiated via SSO and PUC was supposed to be displayed in the popup window or another browser tab.  You can adjust the close.html to close the browser or forward the user to a different login page if desired.

 Until next post, enjoy Pentaho and spring in the upcoming Spring (March 21st)  :)

 -As usual many thanks to my team mates and Pentaho's support team


1 comment: