I'm trying to configure CAS (4.1) to work on a cluster envinronment inside amazon aws. I've configured Tomcat 7 for clustering, but on aws you can't use multicast autodiscovery, so i've set up database session replication on tomcat context. Session replication seems to be working good (other applications inside the same cluster uses it correctly):
<Context path="cas" crossContext="true">
<Manager className="org.apache.catalina.session.PersistentManager" distributable="true" processExpiresFrequency="3" maxIdleBackup="1" >
<Store className="org.apache.catalina.session.JDBCStore"
driverName="org.postgresql.Driver"
connectionURL="jdbc:postgresql://*****:5432/****"
connectionName="*****" connectionPassword="*****"
sessionAppCol="app_name" sessionDataCol="session_data" sessionIdCol="session_id"
sessionLastAccessedCol="last_access" sessionMaxInactiveCol="max_inactive"
sessionTable="persistent_sessions" sessionValidCol="valid_session" />
</Manager>
</Context>
Next i've configured jpaTicketRegistry and uniqueGenerators on cas configuration, like explained in cas configuration guide:
<bean id="cleanerLock"
class="org.jasig.cas.ticket.registry.support.JpaLockingStrategy"
p:uniqueId="${host.name}" p:applicationId="cas-ticket-registry-cleaner" />
<bean id="jobDetailTicketRegistryCleaner"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="ticketRegistryCleaner" p:targetMethod="clean" />
<bean id="triggerJobDetailTicketRegistryCleaner"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
p:jobDetail-ref="jobDetailTicketRegistryCleaner" p:startDelay="20000"
p:repeatInterval="5000000" />
and
<bean id="ticketGrantingTicketUniqueIdGenerator" class="org.jasig.cas.util.DefaultUniqueTicketIdGenerator"
c:maxLength="50" c:suffix="${host.name}" />
<bean id="serviceTicketUniqueIdGenerator" class="org.jasig.cas.util.DefaultUniqueTicketIdGenerator"
c:maxLength="20" c:suffix="${host.name}" />
<bean id="loginTicketUniqueIdGenerator" class="org.jasig.cas.util.DefaultUniqueTicketIdGenerator"
c:maxLength="30" c:suffix="${host.name}" />
<bean id="proxy20TicketUniqueIdGenerator" class="org.jasig.cas.util.DefaultUniqueTicketIdGenerator"
c:maxLength="20" c:suffix="${host.name}" />
<util:map id="uniqueIdGeneratorsMap">
<entry
key="org.jasig.cas.authentication.principal.SimpleWebApplicationServiceImpl"
value-ref="serviceTicketUniqueIdGenerator" />
</util:map>
and
<bean id="ticketGrantingTicketCookieGenerator"
class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
c:casCookieValueManager-ref="cookieValueManager"
p:cookieSecure="true"
p:cookieMaxAge="-1"
p:cookieName="TGC"
p:cookiePath="/cas" />
<bean id="cookieCipherExecutor" class="org.jasig.cas.util.DefaultCipherExecutor"
c:secretKeyEncryption="${tgc.encryption.key}"
c:secretKeySigning="${tgc.signing.key}" />
<bean id="cookieValueManager" class="org.jasig.cas.web.support.DefaultCasCookieValueManager"
c:cipherExecutor-ref="cookieCipherExecutor" />
Now, application is starting up and is working correctly on single node, but when i start the second node, most of time login ticket is not being recognized, and this leads client applications to fail to login:
17:52:48,986 ERROR [http-bio-8443-exec-11][CASFilter:83] org.jasig.cas.client.validation.TicketValidationException: _ Ticket 'ST-1-uFUEA1PDhSv4GPQ61E1T-customers01.dwssystems.com' not recognized_ [Sanitized]
org.jasig.cas.client.validation.TicketValidationException: _ Ticket 'ST-1-uFUEA1PDhSv4GPQ61E1T-customers01.mycompany.com' not recognized_ [Sanitized]
at org.jasig.cas.client.validation.Cas20ServiceTicketValidator.parseResponseFromServer(Cas20ServiceTicketValidator.java:73)
at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:188)
at com.liferay.portal.servlet.filters.sso.cas.CASFilter.processFilter(CASFilter.java:194)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:59)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:109)
at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:169)
at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.java:88)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:59)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:109)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:185)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:96)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
at com.liferay.portal.servlet.filters.urlrewrite.UrlRewriteFilter.processFilter(UrlRewriteFilter.java:57)
at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:59)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:109)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:165)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:96)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:165)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:96)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:185)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:96)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.ha.session.JvmRouteBinderValve.invoke(JvmRouteBinderValve.java:219)
at org.apache.catalina.ha.tcp.ReplicationValve.invoke(ReplicationValve.java:335)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
i'm using different hostnames for the two nodes, as described on cas reference. The ticket is registered inside the database table, but it seems the second node is unable to verify it.
I'm not sure if the problem is about session replication, lack of autodiscovery between nodes or some configuration.