Enabling Single Sign On with CAS in Pentaho+

tenthplanet blog pentaho Enabling Single Sign On with CAS in Pentaho

Pentaho+ Authentication using CAS

1. Pre-requisites

The following Pre-Requisites are in place to configure Pentaho+ BA Server to authenticate users via Centralized Authentication System server.

1. LDAP server is configured for Pentaho+ User and Role Mappings, up and running.

2. Ensure Pentaho+ Server Installed and working fine (EE or CE).

3. Ensure the Pentaho+ Security Feature is updated to LDAP

(security.properties=ldap & applicationContext-security-ldap.properties in [../biserver-ce/pentaho-solutions/system]).

4. Download the war file for cas-server (web application) into any standalone tomcat web server or the tomcat server running along with Pentaho Plus Installation

"cas-server-webapp-3.5.3.war"
 http://central.maven.org/maven2/org/jasig/cas/cas-server-webapp/3.5.3/cas-server-webapp-3.5.3.war 

5. Start Pentaho Plus BA server and verify its working fine by logging in and logging out.

6. Download cas-client-core-3.1.5.jar (from http://repo1.maven.org/maven2/org/jasig/cas/cas-client-core/3.1.5/cas-client-core-3.1.5.jar ) and copy it in [../biserver-ce/tomcat/webapps/pentaho/WEB-INF/lib]

7. Download spring-security-cas-client-2.0.5.RELEASE.jar (from http://repo1.maven.org/maven2/org/springframework/security/spring-security-cas-client/2.0.5.RELEASE/spring-security-cas-client-2.0.5.RELEASE.jar ) and copy it in [../biserver-ce/tomcat/webapps/pentaho/WEB-INF/lib]

2. Environment Details:

  • Pentaho+ BA Server Community Edition / Enterprise Edition 5.4
  • CAS Server Downloaded from third-party (as found in URL specified in above section)
    JAVA 1.7
  • LDAP Configuration using ‘phpldapadmin’ software (Ubuntu OS Server);
  • Configured 2 roles as ‘Admin’ & ‘Authenticated’
  • Created 2 users ‘admin’ (Admin role) & ‘retail’ (Authenticated role); LDAP server runs on 80 port in our server.

3. Installation & Configuration Guidelines

CAS Server Installation

1. Copy the war file downloaded for CAS server application (web application) into any standalone tomcat web server or the tomcat server running along with Pentaho Plus Installation under webapps folder. Once you start/restart the tomcat server, the war will be extracted automatically and must be ready for access via browser.

2. Check war file extraction of CAS server by hitting URL: https://localhost:8443/cas (if your SSL not configured properly, you may see message like the site can’t be reached). Check your SSL configurations or proceed with HTTP URL for now (i.e http://localhost:8080/cas )

Pentaho+ BA Server Installation

1. Copy and paste the ‘cas-client-core-3.1.5.jar’ we downloaded earlier in the path [../biserver-ce/tomcat/webapps/pentaho/WEB-INF/lib]

2. Copy and paste the ‘spring-security-cas-client-2.0.5.RELEASE.jar’we downloaded earlier in the path [../biserver-ce/tomcat/webapps/pentaho/WEB-INF/lib]

Configuring Pentaho+ BA Server for CAS Authentication

1. Open the ‘pentaho-spring-beans.xml’ file in the path [../biserver-ce/pentaho-solutions/system] with any file editor and update it as follows

2. Add to the list of imports after all other applicationContext*.xml files

3. Create a new file with name as “applicationContext-spring-security-cas.xml”

4. Copy the contents of the XML file come along with this documentation in the new file created in above step.

5. Change the configuration of URLs for Pentaho BA server and CAS server as applicable for your environment. By default in our sample code, it will be like “http://localhost:8080/pentaho/ …” for Pentaho BA server related URLs and “http://localhost:8080/cas/ …” for CAS server related URLs.

6. All these URL configurations can be maintained in separate property file for this purpose, and the same can be referred inside the file “applicationContext-spring-security-cas.xml”; Good practice though!.

7. Ensure, if your CAS server or Pentaho Server is enabled for SSL, then use the ‘https://’ & port number as ‘8443’ or as applicable in all places of this XML file where we use URL details of Pentaho/CAS server.

Below is the xml code to be copied into “applicationContext-spring-security-cas.xml”

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:pen="http://www.pentaho.com/schema/pentaho-system"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.pentaho.com/schema/pentaho-system http://www.pentaho.com/schema/pentaho-system.xsd" default-lazy-init="true">

<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
<property name="service" value="http://localhost:8080/bda/j_spring_cas_security_check" />
<property name="sendRenew" value="false" />
</bean>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureUrl" value="http://localhost:8080/cas/authorizationFailure.jsp" />
<property name="defaultTargetUrl" value="/" />
<property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
</bean>
<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
<property name="loginUrl" value="http://localhost:8080/cas/login"/>
<property name="serviceProperties" ref="serviceProperties" />
</bean>
<bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<property name="userDetailsService">
<pen:bean class="org.springframework.security.userdetails.UserDetailsService"/>
</property>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="http://localhost:8080/cas" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
<pen:publish as-type="org.springframework.security.providers.AuthenticationProvider">
<pen:attributes>
<pen:attr key="providerName" value="cas"/>
</pen:attributes>
</pen:publish>
</bean>
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
<![CDATA[CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/webservices/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,
casProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,
filterInvocationInterceptorForWS
/api/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,
casProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,
filterInvocationInterceptorForWS
/plugin/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,
casProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,
filterInvocationInterceptorForWS
/**=securityContextHolderAwareRequestFilter,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,
httpSessionReuseDetectionFilter,logoutFilter,casProcessingFilter,authenticationProcessingFilter,
basicProcessingFilter,requestParameterProcessingFilter,anonymousProcessingFilter,
exceptionTranslationFilter,filterInvocationInterceptor]]>
</value>
</property>
</bean>

<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="casAuthenticationProvider" />
<ref bean="anonymousAuthenticationProvider" />
</list>
</property>
</bean>
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<ref local="casProcessingFilterEntryPoint" />
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.ui.AccessDeniedHandlerImpl" />
</property>
</bean>
<bean id="exceptionTranslationFilterForWS" class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<ref local="casProcessingFilterEntryPoint" />
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.ui.AccessDeniedHandlerImpl" />
</property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
<constructor-arg value="http://localhost:8080/cas/logout?url=http://localhost:8080/bda/Home" />
<!-- URL redirected to after logout -->
<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>
</beans>

4. Test Workflow

  • User attempts to login Pentaho+ (http://localhost:8080/pentaho)
    Application Context file for CAS Authentication, which we added, recognizes the request and redirects it to CAS Server Login Page.
  • User need to enter the username and password appropriately and click on Submit or Login button. The design of this CAS server login screen can be varied / customized based on user demand, as this just like any Java Web Application; Can be configured to get authenticated by LDAP/JDBC/Pentaho Hibernate DB, etc.
  • Currently in our sample, it will work like authentication successful, if username and password are same. Just to make it, we followed this approach.
  • Once authentication successful, the CAS server will generate a ticket about this successful authentication, and redirects the request to Pentaho Plus Home Page along with this ticket.
  • Based on the ticket received, the Pentaho+ BA server assumes the incoming request as a valid session, and search for the authorization privileges for the current session user in the respective data source for ACL details. (In our case we have enabled our Pentaho+ BA server to use LDAP server to get user privilege details).
  • Based on successful authorization, the Pentaho+ Home Page will be loaded for the user.
    In case of trying with user not found in LDAP, the navigation from CAS server to Pentaho+ Home Page will fail in our sample (because authorization fails).

5. Additional Details

HTTPS Configuration (if required):

Generate Security Key:
key tool -genkey -alias cas-server-tpt019 -validity 7000 -keyalg RSA -keypass changeit -storepass changeit -keystore cas.keystore

Export Certificate file for the key generated:
keytool -export -alias cas-server-tpt019 -keypass changeit -file cas-server-tpt019.crt -keystore cas.keystore -storepass changeit

Import the certificate file into your JAVA folder:
key tool -import -file cas-server-tpt019.crt -alias cas-server-tpt019 -keypass changeit -keystore .\..\jre\lib\security\cacerts -storepass changeit

Tomcat configuration on SSL:
Go to section "<!-- Define a SSL HTTP/1.1 Connector on port 8443 ... "):

<Connector URIEncoding="UTF-8" port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"

 maxThreads="150" scheme="https" secure="true"

 clientAuth="false" sslProtocol="TLS"

 keystoreFile="C:/TenthPlanet/Java/jdk1.7.0_55/bin/cas.keystore"

 keystorePass="changeit"

 truststoreFile="C:/TenthPlanet/Java/jdk1.7.0_55/jre/lib/security/cacerts" />

Ensure, the port numbers used here is not overlapping or conflicting with other applications running in this server. keystoreFile, keystorePass, truststoreFile must reflect the settings based on your environment details like path where we generated SSL key, JAVA installation folder, etc.

Verification:

Once done, check with URL like https://localhost:8443 (use port numbers as per your tomcat server.xml file configuration)