Gazelle SSO clients for CAS 5.1.5

This article explains how to connect our application with the "new" version of Apereo CAS 5.1.5.

Maven dependencies

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>

 

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 :

 

<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.

Navigation configuration

You also need to configure your page.xml file to:

  • Configure correctly the logout action (logout from CAS not only from the application)
  • Keep the URL parameters when user logged in

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>

Menu bar configuration

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>

Configuration

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

 

Clean up

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.

Gazelle SSO clients for CAS 5.1.5 (Double CAS authentication)

Maven dependencies

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 :

  • One must extends DoubleCas30ProxyReceivingTicketValidationFilter (for the CAS Validation Filter)
  • The other must extends DoubleLogoutFilter (for the Gazelle CAS logout filter)

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:

  • Configure correctly the logout action (logout from CAS not only from the application)
  • Keep the URL parameters when user logged in

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>