Configuration of CAS Client in Acegi-based apps
The web application side of CAS is made easy due to Acegi
Security. It is assumed you already know the basics of using Acegi
Security, so these are not covered again below. Only the CAS-specific
beans are mentioned.
First of all modify Pentaho’s web.xml to link only one applicationContext file (I’ve called it spring-acegi.xml):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-acegi.xml
</param-value>
</context-param>
You will need to add a ServiceProperties bean
to your application context (spring-acegi.xml).
This represents your service:
<bean id=”serviceProperties” class=”org.acegisecurity.ui.cas.ServiceProperties”>
<property name=”service”>
<value>
https://localhost:8443/pentaho/j_acegi_cas_security_check
</value>
</property>
<property name=”sendRenew”><value>false</value></property>
</bean>
The service must equal a URL that will be monitored by the CasProcessingFilter. The
sendRenew defaults to false, but should be set to true if your application is particularly sensitive. What this parameter does is tell the CAS login service that a single sign on login is unacceptable. Instead, the user will need to re-enter their username and password in order to gain access to the service.
The following beans should be configured to commence the CAS authentication process:
<bean id=”casProcessingFilter” class=”org.acegisecurity.ui.cas.CasProcessingFilter”>
<property name=”authenticationManager”>
<ref bean=”authenticationManager”/>
</property>
<property name=”authenticationFailureUrl”>
<value>/casfailed.jsp</value>
</property>
<property name=”defaultTargetUrl”>
<value>/</value>
</property>
<property name=”filterProcessesUrl”>
<value>/j_acegi_cas_security_check</value>
</property>
</bean>
<bean id=”casProcessingFilterEntryPoint” class=”org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint”>
<property name=”loginUrl”>
<value>https://localhost:8443/cas-server-webapp-3.2.1/login</value>
</property>
<property name=”serviceProperties”>
<ref bean=”serviceProperties”/>
</property>
</bean>
<bean id=”exceptionTranslationFilter” class=”org.acegisecurity.ui.ExceptionTranslationFilter”>
<property name=”authenticationEntryPoint”>
<ref local=”casProcessingFilterEntryPoint”/>
</property>
</bean>
You will also need to add the CasProcessingFilter to web.xml:
<filter>
<filter-name>Acegi CAS Processing Filter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.ui.cas.CasProcessingFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi CAS Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The CasProcessingFilter has very similar properties to the AuthenticationProcessingFilter
(used for form-based logins). Each property is self-explanatory.
For CAS to operate, the ExceptionTranslationFilter must have its authenticationEntryPoint property set to the CasProcessingFilterEntryPoint bean.
The CasProcessingFilterEntryPoint must refer to the ServiceProperties bean (discussed above),
which provides the URL to the enterprise’s CAS login server. This is where the user’s browser will be redirected.
Next you need to add an AuthenticationManager that uses CasAuthenticationProvider and its
collaborators:
<bean id=”authenticationManager” class=”org.acegisecurity.providers.ProviderManager”>
<property name=”providers”>
<list>
<ref bean=”casAuthenticationProvider”/>
</list>
</property>
</bean>
<bean id=”casAuthenticationProvider” class=”org.acegisecurity.providers.cas.CasAuthenticationProvider”>
<property name=”casAuthoritiesPopulator”>
<ref bean=”casAuthoritiesPopulator”/>
</property>
<property name=”casProxyDecider”>
<ref bean=”casProxyDecider”/>
</property>
<property name=”ticketValidator”>
<ref bean=”casProxyTicketValidator”/>
</property>
<property name=”statelessTicketCache”>
<ref bean=”statelessTicketCache”/>
</property>
<property name=”key”>
<value>my_password_for_this_auth_provider_only</value>
</property>
</bean>
<bean id=”casProxyTicketValidator” class=”org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator”>
<property name=”casValidate”>
<value>
https://localhost:8443/cas-server-webapp-3.2.1/proxyValidate
</value>
</property>
<property name=”proxyCallbackUrl”>
<value>
https://localhost:8443/pentaho/casProxy/receptor
</value>
</property>
<property name=”serviceProperties”>
<ref bean=”serviceProperties”/>
</property>
<property name=”trustStore”>
<value>$JAVA_HOME/jre/lib/security/cacerts</value>
</property>
</bean>
<bean id=”cacheManager” class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”>
<property name=”configLocation”>
<value>classpath:/ehcache-failsafe.xml</value>
</property>
</bean>
<bean id=”ticketCacheBackend” class=”org.springframework.cache.ehcache.EhCacheFactoryBean”>
<property name=”cacheManager”>
<ref local=”cacheManager”/>
</property>
<property name=”cacheName”>
<value>ticketCache</value>
</property>
</bean>
<bean id=”statelessTicketCache” class=”org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache”>
<property name=”cache”>
<ref local=”ticketCacheBackend”/>
</property>
</bean>
<bean id=”casAuthoritiesPopulator” class=”org.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator”>
<property name=”userDetailsService”>
<ref bean=”userDetailsService”/>
</property>
</bean>
<bean id=”casProxyDecider” class=”org.acegisecurity.providers.cas.proxy.RejectProxyTickets”/>
Ageci is set up around the inMemoryDaoImpl, four users are defined Admin and User. This DAO is used
to get the credentials for the users who are authenticated by CAS, CAS can only check if a user is authenticated.
See the example below:
<bean id=”userDetailsService” class=”org.acegisecurity.userdetails.memory.InMemoryDaoImpl”>
<property name=”userMap”>
<value>
Admin=***,ROLE_ADMIN,ROLE_AUTHENTICATED
User=***,ROLE_AUTHENTICATED
</value>
</property>
</bean>
Or if you prefer:
<bean id=”userDetailsService”
class=”org.acegisecurity.userdetails.jdbc.JdbcDaoImpl”>
<property name=”dataSource”>
<ref local=”dataSource” />
</property>
<property name=”authoritiesByUsernameQuery”>
<value>
<![CDATA[SELECT username, authority FROM granted_authorities
WHERE username = ?]]>
</value>
</property>
<property name=”usersByUsernameQuery”>
<value>
<![CDATA[SELECT jbp_uname, jbp_password, enabled
FROM jbp_users WHERE jbp_uname = ?]]>
</value>
</property>
</bean>
Note the granted authorities, usually configured in acegi security, are ignored by CAS because
it has no way of communicating the granted authorities to calling applications.
CAS is only concerned with username and passwords (and the enabled/disabled status).
In this implementation of userDetailsService we use default ROLE_* name definition.
If you want to mantain (for easy understanding) roles coming from CAS credentials remember to
write “ROLE_” prefix before your desired Role, otherwise you’ll obtain an error response
(about UNKNOWN ROLE) while deploying pentaho.war.
Otherwise try to modify role_prefix property to anoter prefix…
see Spring acegi security documentation for this.
If you have to use proxyTickets:
Note the
CasProxyTicketValidatorhas a remarked outtrustStoreproperty. This property might be helpful if you experience HTTPS certificate issues. Also note theproxyCallbackUrlis set so the service can receive a proxy-granting ticket. As mentioned above, this is optional and unnecessary if you do not require proxy-granting tickets. If you do use this feature, you will need to configure a suitable servlet to receive the proxy-granting tickets. We suggest you use CAS’ProxyTicketReceptorby adding the following to yourweb application’sweb.xml:
<servlet>
<servlet-name>casproxy</servlet-name>
<servlet-class>edu.yale.its.tp.cas.proxy.ProxyTicketReceptor</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>casproxy</servlet-name>
<url-pattern>/casProxy/*</url-pattern>
</servlet-mapping>
Finally for logout from Pentaho you need to add the following:
<bean id=”logoutFilter” class=”org.acegisecurity.ui.logout.LogoutFilter”>
<constructor-arg value=”https://administrator-desktop:8443/cas-server-webapp-3.2.1/logout”>
<constructor-arg>
<list>
<bean class=”com.pentaho.security.ProPentahoLogoutHandler”>
<bean class=”org.acegisecurity.ui.logout.SecurityContextLogoutHandler”>
</bean>
</bean>
<property name=”filterProcessesUrl” value=”/Logout”>
</property></list></constructor-arg></constructor-arg></bean>
and remember to add “logoutFilter” to filterChainProxy at the beginning of the configuration file.
This completes the configuration of CAS. If you haven’t made any mistakes, your web application should happily work within the framework of CAS single sign on. No other parts of Acegi Security need to be concerned about the fact CAS handled authentication.
A full example of applicationContext file is here.
Just adapt it to Pentaho’s and CAS configuration parameters.
This guide was written looking at:
If I made some mistakes please post here your suggestions…
Thanks a lot.
Alla fine l’hai spostato eh? brav brav
come ti trovi con wordpress?
Da: Giuseppe Aniello su Luglio 31, 2008
alle 6:43 pm
benissimo…però mi sa che ho imparato una cosa…prima scrivo con word e poi lo importo con la funzione che ha il wysiwyg di wordpress, che è na figata…
Da: pasquale rizzi su Agosto 1, 2008
alle 7:42 am
Now I am at the last step and stuck again.
With pentaho.war deployed, I get the same problem as before. If I remove it, the portal + CAS works.
The exception is:
09:26:49,500 INFO [STDOUT] 2008-08-19 09:26:49,500 INFO [org.jasig.cas.CentralA
uthenticationServiceImpl] –
09:26:49,546 ERROR [STDERR] 2008/08/19 09:26:49:546 CEST [ERROR] CASReceipt – ed
u.yale.its.tp.cas.client.CASAuthenticationException: Unable to validate ProxyTic
ketValidator [[edu.yale.its.tp.cas.client.ProxyTicketValidator proxyList=[null]
[edu.yale.its.tp.cas.client.ServiceTicketValidator casValidateUrl=[https://local
host/cas/serviceValidate] ticket=[ST-3-tygpLb0vUtBIOdxC1eQuKiHQQD62N6R4QYK-20] s
ervice=[https%3A%2F%2Flocalhost%3A443%2Fportal%2Fauthsec%2Fportal%2Fdefault%2Fde
fault] renew=false]]]
So it must be a problem with the pentaho.war.
I have downloaded the spring-acegi.xml and adapted the port (I use 443).
In the web.xml there is already a filter similar to what you add:
Acegi Filter Chain Proxy
org.acegisecurity.util.FilterToBeanProxy
targetBean
filterChainProxy
Do you have to combine them? O remove this one? The filter class is the same.
Before, I get also the error:
09:25:39,750 ERROR [STDERR] 2008/08/19 09:25:39:750 CEST [ERROR] Logger – misc-org.pentaho.core.system.PentahoSystem: PentahoSystem.ERROR_0007 – userDetailsRoleListService property of PentahoSystem has not been set. Make sure that an instance of UserDetailsRoleListService is defined in a Spring XML file. Note that UserDetailsRoleListService will attach itself automatically to PentahoSystem. It simply needs to be defined in Spring.
09:25:39,750 ERROR [STDERR] [es_68] Pentaho BI Platform server failed to properly initialize. The system will not be available for requests.
That is a bean in WEB-INF/applicationContext-pentaho-security-memory.xml which is not defined in the spring-acegi.xml. Do you have to add it?
I use Pentaho 1.7.0.
Grazie mile
Da: ulrich su Agosto 19, 2008
alle 7:34 am
Hi,
for Acegi Filter Chain Proxy you have to add another filter entry to your web.xml:
FOR SPRING.ACEGI.XML
i don’t use userDetailsRoleListService.
So if you can, remove its definition.
If you have toubles post your spring.acegi.xml or better make it available on the web and post the link…
Da: pasquale rizzi su Agosto 19, 2008
alle 2:43 pm
If I don’t define userDetailsRoleListService in the spring xml file, I get the error above and Pentaho does not start. So I don’t understand how does it work for you without it. Which version of Pentaho do you use?
I tried to add all bean dependencies for userDetailsRoleListService. Then the application starts, but I get still the original problem (Unable to validate ProxyTicketValidator).
If you send me an email, I can send you the spring-acegi.xml file. (I put you also a message in Pentaho).
Thanks
Da: ulrich su Agosto 19, 2008
alle 3:26 pm
Please post your spring.acegi.xml here.
In your reply you can attach your spring.cegi.xml..
and I’ll help you…
Da: pasquale rizzi su Agosto 19, 2008
alle 4:22 pm
you have to remove beans “pentahoUserRoleListService”, “inMemoryUserRoleListService” and all beans related to them…
better from bean “pentahoUserRoleListService” to “</beans>” shift-ctrl-end then canc…this is the solution.
I think that you have to read more about spring acegi security with cas integration and you’ll have serenity in mind…
Da: pasquale rizzi su Agosto 19, 2008
alle 8:09 pm
Well, that was my first trial.
When I remove the pentaho beans stuff from spring-acegi.xml, I get again
Have you tried with version 1.7.0? Maybe there is a change wrt older versions.
And the CAS login does not work:
Thanks
Da: ulrich su Agosto 20, 2008
alle 10:54 am
Dove si possono trovare programmatori esperti della piattaforma Pentaho??
Da: Francesco su Dicembre 13, 2008
alle 4:26 pm
per programmatori cosa intendi?
sviluppatori della piattaforma?o esperti nell’utilizzo della piattaforma e delle sue integrazioni?
Da: pasquale rizzi su Dicembre 16, 2008
alle 8:57 am
Grazie per gli articoli perchè mi sono stati di molto aiuto. Ti volevo chiedere se quanto descritto rimane valido anche nel caso in cui Pentaho sia su Tomcat 5.5 ?
Da: maurizio su Marzo 5, 2009
alle 12:22 am
ovviamente sì, devi solo documentarti su come integrare cas in tomcat ma è relativamente semplice. A riguardo c’è molta documentazione…
Da: pasquale rizzi su Marzo 5, 2009
alle 9:50 am
Ok grazie, solo per riassumere:
Il mio problema è integrare un portale definito in Jboss-portal-2-7.1 con pentaho installatato su Tomcat 5.5.
(1) Integro CAS in jboss cosi come hai descritto nei tuoi articoli.
(2) Integro CAS in tomcat.
(3) Configuro Pentaho.
Grazie ed un saluto
Da: maurizio su Marzo 5, 2009
alle 4:44 pm
Attento però…se jboss-portal e pentaho girano su due application server differenti devi seguire altre strade.
Il single sign-on generalmente lo si usa per poter condividere un unico accesso ad applicazioni diferenti residenti sullo stesso application server.
Da quel che mi sembra di capire tu utilizzi due application servers diversi: uno per jboss-portal e uno per tomcat…quindi la strada da seguire è un’altra
Da: pasquale rizzi su Marzo 5, 2009
alle 4:51 pm
I’m getting into redirect loop problem… with following url: https://localhost:8443/cas-server-webapp-3.3.1/login?service=http%3A%2F%2Flocalhost%3A8080%2Fpentaho%2Fj_acegi_cas_security_check
can someone help me?
Da: salmon su Marzo 19, 2009
alle 12:55 pm
Redirect Loop could have more causes:
1) The user tries to access a service protected by a CAS client.
2) The CAS client sees that the user does not have a local session
and did not bring a ticket, so it redirects the user to the CAS
server.
3) The user logs in at the CAS server and establishes a session
(i.e. TGT) with the CAS server.
4) The CAS server redirects the user back to the original service.
5) The service sees the ticket and tries to validate it, but cannot
do so for any number of reasons. Such reason might be:
a) The CAS client is misconfigured
b) A firewall blocks connection between the client and server
c) The server is malfunctioning
d) The CAS server replies with a validation failure response
6) Now, in this situation, the client should issue an error message
to the user, but some client’s don’t. Instead, we get this:
The CAS client redirects the user back to the CAS server.
7) The CAS server sees that the users has already authenticated, so
it creates a new service ticket and redirects the user back to
the original service.
Please Review your settings about cas and redirecting after login…
Da: pasquale rizzi su Marzo 19, 2009
alle 3:15 pm
Thanx for response…
problem was, that I forget to put casProcessingFilter into filterChainProxy…
Da: salmon su Marzo 20, 2009
alle 10:57 am
I need to implement single sign out… can you help?
Da: salmon su Marzo 25, 2009
alle 2:41 pm
Follow last lines of this guide…where it says:”Finally for logout from Pentaho you need to add the following:”
Da: pasquale rizzi su Marzo 25, 2009
alle 4:20 pm