This article explains how to connect our application with the "new" version of Apereo CAS 5.1.5.
In your ejb pom.xml you need to have cas-client-core as dependency.
<dependency> <groupId>net.ihe.gazelle</groupId> <artifactId>gazelle-cas-client</artifactId> <version>1.0.0</version> </dependency>
Warning, if you have a parent that include the previous cas-client (3.1.10.IHE.1), you must exclude it. Example with simulator-common as parent, you must add the following in you ejb pom.xml :
<dependency> <groupId>net.ihe.gazelle.simulators</groupId> <artifactId>simulator-common-ejb</artifactId> <type>ejb</type> <exclusions> <exclusion> <groupId>org.jasig.cas</groupId> <artifactId>cas-client-core</artifactId> </exclusion> </exclusions> </dependency>
Now you need to update the WEB-INF/web.xml file in your war module.
First remove all previous filters and properties that concern the CAS, then add the followings elements :
<context-param> <param-name>configurationStrategy</param-name> <param-value>PROPERTY_FILE</param-value> </context-param> <context-param> <param-name>configFileLocation</param-name> <param-value>/opt/gazelle/cas/file.properties</param-value> </context-param> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener> <filter> <filter-name>Gazelle CAS Authentication Filter</filter-name> <filter-class>net.ihe.gazelle.cas.client.authentication.AuthenticationFilter</filter-class> </filter> <filter-mapping> <filter-name>Gazelle CAS Authentication Filter</filter-name> <url-pattern>/cas/login</url-pattern> </filter-mapping> <filter> <filter-name>Gazelle CAS logout filter</filter-name> <filter-class>net.ihe.gazelle.cas.client.authentication.LogoutFilter</filter-class> </filter> <filter-mapping> <filter-name>Gazelle CAS logout filter</filter-name> <url-pattern>/cas/logout.seam</url-pattern> </filter-mapping> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter </filter-class> </filter> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Then add, still in web.xml the following configuration properties:
<context-param> <param-name>configurationStrategy</param-name> <param-value>PROPERTY_FILE</param-value> </context-param> <context-param> <param-name>configFileLocation</param-name> <param-value>/opt/gazelle/cas/file.properties</param-value> </context-param>
The last one indicates where the gazelle-cas-client will find information to connect with the CAS server.
You also need to configure your page.xml file to:
To do so, configuration the navigation section as shown below
<page view-id="*"> <navigation from-action="#{identity.logout}"> <rule if="#{!applicationConfigurationManager.isWorksWithoutCas()}"> <redirect view-id="/cas/logout.xhtml"/> </rule> <rule if="#{applicationConfigurationManager.isWorksWithoutCas()}"> <redirect view-id="/home.xhtml"/> </rule> </navigation> </page> <page view-id="/cas/login"> <navigation> <redirect view-id="/home.xhtml"/> </navigation> </page>
The links in your menu bar shall look like the following:
<h:panelGroup rendered="#{identity.loggedIn}"> <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> <h:outputText id="menuWelcomeId" value="#{credentials.username}"/> <span class="caret"/> </a> <ul class="dropdown-menu" role="menu"> <li> <s:link id="menuLogoutId" view="/home.seam" action="#{identity.logout()}" value="#{messages['net.ihe.gazelle.simulators.Logout']}" propagation="none"/> </li> </ul> </li> </h:panelGroup> <h:panelGroup> <li> <a4j:commandLink value="#{messages['gazelle.simulator.Login']}" action="#{applicationConfiguration.loginByIP()}" rendered="#{not identity.loggedIn and applicationConfigurationManager.isWorksWithoutCas()}"/> </li> <li> <s:link id="menuLoginCasId" view="/cas/home.seam" value="#{messages['gazelle.simulator.loginCAS']}" rendered="#{not identity.loggedIn and not applicationConfigurationManager.isWorksWithoutCas()}" propagation="none"> <f:param name="request" value="#{request.requestURL}" disable="#{request.queryString != null}"/> <f:param name="request" value="#{request.requestURL}?#{request.queryString}" disable="#{request.queryString == null}"/> </s:link> </li> </h:panelGroup>
Next step is to create the configuration file declared in your deployment decriptor.
On the system where the application is deployed, create the file /opt/gazelle/cas/file.properties containing:
serverName=http://localhost casServerUrlPrefix=https://sso.ihe-europe.net/cas casServerLoginUrl=https://sso.ihe-europe.net/cas/login casLogoutUrl=https://sso.ihe-europe.net/cas/logout
The application preference cas_url is no longer required, think about removing it with an update.sql script in the next release.
Extensions of AuthenticationFilter and Cas20ProxyReceivingTicketValidationFilter classes are no longer requeried, do not forget to remove them.
Add as dependency in your ejb
<dependency>
<groupId>net.ihe.gazelle</groupId>
<artifactId>gazelle-cas-client</artifactId>
<version>${gazelle.cas.client.version}</version>
</dependency>
Web deployment descriptor
Now you need to update the WEB-INF/web.xml file in your war module.
First remove all previous filters and properties that concern the CAS, then add the followings elements
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>net.ihe.gazelle.atna.questionnaire.authentication.GSSDoubleCasTicketValidationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>Gazelle CAS logout filter</filter-name>
<filter-class>net.ihe.gazelle.atna.questionnaire.authentication.GSSDoubleLogoutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Gazelle CAS logout filter</filter-name>
<url-pattern>/cas/logout</url-pattern>
</filter-mapping>
<filter>
<filter-name>Gazelle Main CAS Authentication Filter</filter-name>
<filter-class>net.ihe.gazelle.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>cas</param-name>
<param-value>main</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Gazelle Main CAS Authentication Filter</filter-name>
<url-pattern>/cas/login</url-pattern>
</filter-mapping>
<filter>
<filter-name>Gazelle Second CAS Authentication Filter</filter-name>
<filter-class>net.ihe.gazelle.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>cas</param-name>
<param-value>second</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Gazelle Second CAS Authentication Filter</filter-name>
<url-pattern>/cas/login2</url-pattern>
</filter-mapping>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
This example is for Gazelle Security Suite, the filter-class of Gazelle CAS logout filter and CAS Validation Filter need to be changed if you use this in another tool. The classes must be created in your project :
In both case, 3 functions need to be implemented (check on atna-questionnaire to see an exemple) :
public abstract void computeUserSCas(ServletRequest servletRequest);
public abstract CasLogin getCasLoginForUser(ServletRequest servletRequest);
public abstract boolean isSecondCasEnabled();
Then add, still in web.xml the following configuration properties
<context-param>
<param-name>configurationStrategy</param-name>
<param-value>net.ihe.gazelle.cas.client.doubleauthentication.PropertiesConfigurationStrategyImpl</param-value>
</context-param>
<context-param>
<param-name>configFileLocationMainCas</param-name>
<param-value>/opt/gazelle/cas/file.properties</param-value>
</context-param>
<context-param>
<param-name>configFileLocationSecondCas</param-name>
<param-value>/opt/gazelle/cas/file_second_cas.properties</param-value>
</context-param>
The two last one indicates where the gazelle-cas-client will find information to connect with the CAS server.
You also need to configure your page.xml file to:
To do so, configuration the navigation section as shown below
<page view-id="*">
<navigation from-action="#{identity.logout}">
<rule if="#{!applicationConfigurationManager.isWorksWithoutCas()}">
<redirect view-id="/cas/logout.xhtml"/>
</rule>
<rule if="#{applicationConfigurationManager.isWorksWithoutCas()}">
<redirect view-id="/home.xhtml"/>
</rule>
</navigation>
</page>
<page view-id="/cas/identityLogout.xhtml">
<action execute="#{identity.logout}"/>
<navigation>
<redirect view-id="/home.xhtml"/>
</navigation>
</page>
<page view-id="/cas/login">
<navigation>
<redirect view-id="/home.xhtml"/>
</navigation>
</page>
<page view-id="/cas/login2">
<navigation>
<redirect view-id="/home2.xhtml"/>
</navigation>
</page>
Menu bar configuration
The links in your menu bar shall look like the following (login then logout) :
<li>
<h:outputLink id="menuLoginCasId2" value="#{applicationConfiguration.getValueOfVariable('application_url')}/cas/login">
<h:outputText value="#{applicationAttributes.getMainCasName()}"/>
<f:param name="request" value="#{request.requestURL}" disable="#{request.queryString != null}"/>
<f:param name="request" value="#{request.requestURL}?#{request.queryString}" disable="#{request.queryString == null}"/>
<f:param name="cas" value="main"/>
</h:outputLink>
</li>
<li>
<h:outputLink id="menuLoginCasId3" value="#{applicationConfiguration.getValueOfVariable('application_url')}/cas/login2">
<h:outputText value="#{applicationAttributes.getSecondCasName()}"/>
<f:param name="request" value="#{request.requestURL}" disable="#{request.queryString != null}"/>
<f:param name="request" value="#{request.requestURL}?#{request.queryString}" disable="#{request.queryString == null}"/>
<f:param name="cas" value="second"/>
</h:outputLink>
</li>