- Download CAS Server. Choose the latest version (3.5.2) and extract cas-server-webapp-3.5.2.war from modules folder. Rename it to cas.war and copy that file to D:\pentaho\biserver-ce\tomcat\webapps\. When Tomcat is running, it will extract that file to new folder named cas.
Also extract cas-server-support-jdbc-3.5.2.jar from modules folder and copy that file to D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF\lib\.
And copy commons-dbcp-1.4.jar and commons-pool-1.5.7.jar from D:\pentaho\biserver-ce\tomcat\webapps\pentaho\WEB-INF\lib\ to D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF\lib\ - Download CAS Client. Choose latest version (cas-client-core-3.2.1.jar) and copy that file to D:\pentaho\biserver-ce\tomcat\webapps\pentaho\WEB-INF\lib\
- Download Spring Security CAS Client version 2.0.5. Place that file in D:\pentaho\biserver-ce\tomcat\webapps\pentaho\WEB-INF\lib\
- Create security certificate. Run as administrator this command in command prompt (cmd).
- Edit server.xml in D:\pentaho\biserver-ce\tomcat\conf\
- Edit cas.properties in D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF
- Edit cas.servlet.xml in D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF
- Edit deployerConfigContext.xml in D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF
- Create new file named applicationContext-spring-security-cas.xml in D:\pentaho\biserver-ce\pentaho-solutions\system\ and copy paste this code to that file.
- Edit pentaho-spring-beans.xml in D:\pentaho\biserver-ce\pentaho-solutions\system\
- Edit web.xml in D:\pentaho\biserver-ce\tomcat\webapps\pentaho\WEB-INF
- Restart tomcat and open http://localhost:8080/pentaho, we will be redirected to https://localhost:8443/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fpentaho%2Fj_spring_cas_security_check. Now when you log in/out from CAS, you will be logged in/out from all application you integrated with CAS.
- Let's have a drink and party! ;)
"%JAVA_HOME%"\bin\keytool -delete -alias tomcat -keypass changeit
"%JAVA_HOME%"\bin\keytool -genkey -alias tomcat -keypass changeit -keyalg RSA
"%JAVA_HOME%"\bin\keytool -export -alias tomcat -keypass changeit -file server.crt
"%JAVA_HOME%"\bin\keytool -import –alias tomcat -file server.crt -keypass changeit -keystore "%JAVA_HOME%"\jre\lib\security\cacerts
Add this part
<Connector URIEncoding="UTF-8" port="8443"
protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"keystoreFile="D:/Fabian/.keystore"
keyAlias="tomcat" keystorePass="changeit"
truststoreFile="C:/Program Files/Java/jdk1.7.0_10/jre/lib/security/cacerts" clientAuth="false"
sslProtocol="TLS" />
Before this part
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector URIEncoding="UTF-8" port="8009" protocol="AJP/1.3" redirectPort="8443" />
Change yellow highlighted part according to user profile and JDK path.
Change this part
server.name=http://localhost:8080
With this part
server.name=https://localhost:8443
Comment this part
<webflow:flow-execution-listeners>
<webflow:listener ref="terminateWebSessionListener" />
</webflow:flow-execution-listeners>
Become this
<!--
<webflow:flow-execution-listeners>
<webflow:listener ref="terminateWebSessionListener" />
</webflow:flow-execution-listeners>
-->
Replace or comment this part
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
With this part
<bean class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
<property name="tableUsers"><value>Users</value></property>
<property name="fieldUser"><value>user_name</value></property>
<property name="fieldPassword"><value>pwdhash</value></property>
<property name="dataSource" ref="dataSource"/>
<property name="passwordEncoder">
<bean class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" p:characterEncoding="UTF-16LE" >
<constructor-arg index="0" value="SHA1" />
</bean>
</property>
</bean>
Highlighted part is database table setting used for authentication. For this tutorial I use Users table with users_name as user id field and pwdhash as password field. Password encoded by SHA1 method. Encoding UTF-16LE used by Microsoft SQL Server (yes, it's not UTF-16 like in other database engine).
Still in the same file, add this part
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>net.sourceforge.jtds.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:jtds:sqlserver://localhost:1433/MainDB</value>
</property>
<property name="username"><value>authentication</value></property>
<property name="password"><value>test123</value></property>
</bean>
Before this part (last line)
</beans>
It is database configuration. I use SQL Server with jtds driver and authentication and test123 as database username and password and MainDB as database name. Copy jtds-1.3.1.jar from D:\pentaho\biserver-ce\tomcat\lib\ to D:\pentaho\biserver-ce\tomcat\webapps\cas\WEB-INF\lib\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springsource.org/dtd/spring-beans.dtd">
<beans default-autowire="no" default-dependency-check="none" default-lazy-init="false">
<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy" autowire="default" dependency-check="default" lazy-init="default">
<property name="filterInvocationDefinitionSource">
<value>
<![CDATA[CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=securityContextHolderAwareRequestFilter,httpSessionContextIntegrationFilter,logoutFilter,casProcessingFilter,basicProcessingFilter,requestParameterProcessingFilter,anonymousProcessingFilter,pentahoSecurityStartupFilter,exceptionTranslationFilter,filterInvocationInterceptor,casSingleSignOutFilter]]>
</value>
</property>
</bean>
<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties" autowire="default" dependency-check="default" lazy-init="default">
<property name="service" value="http://localhost:8080/pentaho/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter" autowire="default" dependency-check="default" lazy-init="default">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="authenticationFailureUrl" value="/public/casFailed"/>
<property name="defaultTargetUrl" value="/"/>
<property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>
</bean>
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" />
<bean id="casSingleSignOutHttpSessionListener" class="org.jasig.cas.client.session.SingleSignOutHttpSessionListener" />
<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter" autowire="default" dependency-check="default" lazy-init="default">
<property name="authenticationEntryPoint">
<ref local="casProcessingFilterEntryPoint"/>
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.ui.AccessDeniedHandlerImpl" />
</property>
</bean>
<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint" autowire="default" dependency-check="default" lazy-init="default">
<property name="loginUrl" value="https://localhost:8443/cas/login"/>
<property name="serviceProperties">
<ref local="serviceProperties"/>
</property>
</bean>
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager" autowire="default" dependency-check="default" lazy-init="default">
<property name="providers">
<list>
<ref bean="anonymousAuthenticationProvider"/>
<ref bean="casAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<property name="userDetailsService">
<ref bean="userDetailsService"/>
</property>
<property name="serviceProperties">
<ref local="serviceProperties"/>
</property>
<property name="ticketValidator">
<ref local="ticketValidator"/>
</property>
<property name="key" value="my_password_for_this_auth_provider_only"/>
</bean>
<bean id="ticketValidator" class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator" autowire="default" dependency-check="default" lazy-init="default">
<constructor-arg index="0" value="https://localhost:8443/cas"/>
</bean>
<bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter" autowire="default" dependency-check="default" lazy-init="default">
<constructor-arg value="https://localhost:8443/cas/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>
<bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener" />
<bean id="basicProcessingFilter" class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager">
<ref local="authenticationManager" />
</property>
<property name="authenticationEntryPoint">
<ref local="basicProcessingFilterEntryPoint" />
</property>
</bean>
<bean id="basicProcessingFilterEntryPoint" class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
<property name="realmName" value="Pentaho Realm" />
</bean>
<bean id="requestParameterProcessingFilter" class="org.pentaho.platform.web.http.security.RequestParameterAuthenticationFilter">
<property name="authenticationManager">
<ref local="authenticationManager" />
</property>
<property name="authenticationEntryPoint">
<ref local="requestParameterProcessingFilterEntryPoint" />
</property>
</bean>
<bean id="requestParameterProcessingFilterEntryPoint" class="org.pentaho.platform.web.http.security.RequestParameterFilterEntryPoint" />
<bean id="pentahoSecurityStartupFilter" class="org.pentaho.platform.web.http.security.SecurityStartupFilter">
<property name="injectAnonymous" value="true" />
</bean>
<bean id="anonymousProcessingFilter" class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="foobar" />
<property name="userAttribute" value="anonymousUser,Anonymous" />
</bean>
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="foobar" />
</bean>
<bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
<bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />
<bean id="httpSessionReuseDetectionFilter" class="org.pentaho.platform.web.http.security.HttpSessionReuseDetectionFilter">
<property name="filterProcessesUrl" value="/j_spring_security_check" />
<property name="sessionReuseDetectedUrl" value="/Login?login_error=2" />
</bean>
<bean id="httpRequestAccessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<ref bean="roleVoter" />
</list>
</property>
</bean>
<bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager">
<ref local="authenticationManager" />
</property>
<property name="accessDecisionManager">
<ref local="httpRequestAccessDecisionManager" />
</property>
<property name="objectDefinitionSource">
<value>
<![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/docs/.*\Z=Anonymous,Authenticated,ea_admin
\A/mantlelogin/.*\Z=Anonymous,Authenticated,ea_admin
\A/mantle/mantleloginservice/*\Z=Anonymous,Authenticated,ea_admin
\A/mantle/.*\Z=Authenticated,ea_admin
\A/welcome/.*\Z=Anonymous,Authenticated,ea_admin
\A/public/.*\Z=Anonymous,Authenticated,ea_admin
\A/login.*\Z=Anonymous,Authenticated,ea_admin
\A/ping/alive.gif.*\Z=Anonymous,Authenticated,ea_admin
\A/j_spring_security_check.*\Z=Anonymous,Authenticated,ea_admin
\A/getimage.*\Z=Anonymous,Authenticated,ea_admin
\A/getresource.*\Z=Anonymous,Authenticated,ea_admin
\A/admin.*\Z=Admin,uidai_admin
\A/auditreport.*\Z=Admin,uidai_admin
\A/auditreportlist.*\Z=Admin,uidai_admin
\A/versioncontrol.*\Z=Admin,uidai_admin
\A/propertieseditor.*\Z=Admin,uidai_admin
\A/propertiespanel.*\Z=Admin,uidai_admin
\A/subscriptionadmin.*\Z=Admin,uidai_admin
\A/resetrepository.*\Z=Admin,uidai_admin
\A/viewaction.*solution.admin.*\Z=Admin,uidai_admin
\A/scheduleradmin.*\Z=Admin,uidai_admin
\A/publish.*\Z=Admin,uidai_admin
\A/logout.*\Z=Anonymous
\A/solutionrepositoryservice.*component=delete.*solution=system.*\Z=Nobody
\A/solutionrepositoryservice.*solution=system.*component=delete.*\Z=Nobody
.*system.*pentaho.xml.*=Nobody
.*system.*applicationcontext.*.xml.*=Nobody
.*system.*pentahoobjects.spring.xml.*=Nobody
.*system.*pentahosystemconfig.xml.*=Nobody
.*system.*adminplugins.xml.*=Nobody
.*system.*plugin.properties.*=Nobody
.*system.*publisher_config.xml.*=Nobody
.*system.*sessionstartupactions.xml.*=Nobody
.*system.*systemlisteners.xml.*=Nobody
.*system.*hibernate.*=Nobody
.*system.*birt/.*=Nobody
.*system.*dialects/.*=Nobody
.*system.*google/.*=Nobody
.*system.*jasperreports/.*=Nobody
.*system.*jfree/.*=Nobody
.*system.*kettle/.*=Nobody
.*system.*logs/.*=Nobody
.*system.*metadata/.*=Nobody
.*system.*mondrian/.*=Nobody
.*system.*olap/.*=Nobody
.*system.*quartz/.*=Nobody
.*system.*simple-jndi/.*=Nobody
.*system.*smtp-email/.*=Nobody
.*system.*ui/.*=Nobody
.*system.*analysistemplate.tpl.*=Nobody
.*system.*\.\./.*=Nobody
\A/.*\Z=Authenticated,ea_admin
]]>
</value>
</property>
</bean>
</beans>
Change this part
<import resource="applicationContext-spring-security.xml" />
Become this part
<import resource="applicationContext-spring-security-cas.xml" />
Add this part
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
Before this part
<filter> <!-- This must be the first filter listed in the web.xml -->
<filter-name>Set Character Encoding Filter</filter-name>
<filter-class>org.pentaho.platform.web.http.filters.PentahoAwareCharacterEncodingFilter</filter-class>
<init-param>
<param-name>ignore</param-name>
<param-value>yes</param-value>
</init-param>
</filter>
Add this part
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Before this part
<filter-mapping>
<filter-name>Set Character Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Add this part
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
After this part
<listener>
<listener-class>org.pentaho.platform.web.http.session.PentahoCacheSessionListener</listener-class>
</listener>
No comments:
Post a Comment