Single Sign Out

New CAS documentation site

CAS documentation has moved over to apereo.github.io/cas, starting with CAS version 4.x. The wiki will no longer be maintained. For the most recent version of the documentation, please refer to the aforementioned link.

CAS 3.1 is designed to support single sign out. Whenever a Ticket Granting Ticket is explicitly expired, the logout protocol will be initiated. Clients that do not support the logout protocol may notice extra requests in their access logs that appear not to do anything.

Where Single Sign Out Works:

  • Clients / Languages whose session management is maintained on the server side. CAS clients can then access session information to end the session.

Where Single Sign Out "Doesn't Work" :

How it works:

When a CAS session ends, it will callback to each of the services that are registered with the system and send a POST request with the following:

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="[RANDOM ID]" Version="2.0" IssueInstant="[CURRENT DATE/TIME]">
    <saml:NameID>@NOT_USED@</saml:NameID>
    <samlp:SessionIndex>[SESSION IDENTIFIER]</samlp:SessionIndex>
</samlp:LogoutRequest>

The URL that will be POSTed to is the original service url.

At this moment the session identifier is the same as the CAS Service Ticket (the service ticket should be sufficiently long to be secure). The session identifier should map back to a session which can be terminated (i.e. deleted from a database, expired, etc.)

Alternative future choices for this protocol would be to transfer the LogoutRequest via SOAP (like SAML 1.1 responses).

Disabling Single Sign Out on the Server

Because not all clients support single sign out, you may need to disable it at the server level. 

CAS server version 4.0.x

Since this version, the property slo.callbacks.disabled exists for the LogoutManagerImpl class (instead of the CasArgumentExtractor class) :

<bean id="logoutManager" class="org.jasig.cas.logout.LogoutManagerImpl">
    <constructor-arg index="0" ref="servicesManager"/>
    <constructor-arg index="1" ref="noRedirectHttpClient"/>
    <property name="disableSingleSignOut" value="${slo.callbacks.disabled:false}" />         
</bean>

CAS server version 3.5.x

In that version, a property defines whether the Single Sign Out is disabled : slo.callbacks.disabled.

<bean id="casArgumentExtractor" class="org.jasig.cas.web.support.CasArgumentExtractor"
    p:httpClient-ref="noRedirectHttpClient"
    p:disableSingleSignOut="${slo.callbacks.disabled:false}" />

CAS server version <= 3.4.x

Each ArgumentExtractor has a property called "disableSingleSignOut", which if set to true will make sure the callback does not occur. To set it to true (i.e. turn off the "single sign-off" callback) edit your argumentExtractorsConfiguration.xml file as follows:

<bean id="casArgumentExtractor" class="org.jasig.cas.web.support.CasArgumentExtractor"
      p:httpClient-ref="httpClient"
      p:disableSingleSignOut="true" />

<bean id="samlArgumentExtractor" class="org.jasig.cas.web.support.SamlArgumentExtractor"
      p:httpClient-ref="httpClient"
      p:disableSingleSignOut="true" />

Disabling Single Sign Out on Ticket Registry Cleaner

CAS default behavior is to issue single sign out callbacks in response to a /cas/logout request or when a TGT is expired via expiration policy when a TicketRegistryCleaner runs.  If you are using ticket registry cleaner, and you want to enable the single sign out callback only when CAS receives a request to /cas/logout you can configure your TicketRegistryCleaner like so:

<bean id="ticketRegistryCleaner" class="org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner"
      p:ticketRegistry-ref="ticketRegistry"
      p:lock-ref="cleanerLock"
      p:logUserOutOfServices="false" />

Also note that some ticket registries don't use or need a registry cleaner, such as the Memcahed and Ehcache ticket registries. If you so decide to implement EhCache, the option of having a ticker registry cleaner is entirely done away with and is currently not implemented. With that being absent, you will no longer receive automatic SLO callbacks upon TGT expiration. As such, the only thing that would reach back to the should then be the /logout command issued to CAS. 

Distributed vs non-distributed ticket registry behavior

Default in-memory ticket registry with a cleaner:

1. Suppose that logUserOutOfServices is set to true
2. The cleaner runs to detect the ticket that are automatically expired. It will query the tickets in the ticket registry, and will accumulate those that are expired.
3. For the collection of expired tickets, with logUserOutOfServices=true, the cleaner will again ask them to “expire”. This is just a technical detail that triggers the SLO callback to be issued.
4. Note: if logUserOutOfServices is set to false, the cleaner will not attempt to “expire” the ticket, so no automatic SLO callbacks.
5. The cleaner subsequently removes the ticket [TGT] from the registry.

Please note that simply removing a ticket by itself from the registry does not issue the SLO callback. A ticket needs to be explicitly told one way or another, to “expire” itself.

The logic of that is described below:

  • If the ticket is already expired, the mechanism will issue the SLO callback.
  • If the ticket is not already expired, it will be marked as expired and the SLO callback will be issued.

Distributed ticket registry, such as EhCache, no cleaner:


1. There’s no cleaner, so nothing runs in the background or otherwise to “expire” and delete tickets from the registry and thus, no SLO callbacks will be issued automatically.
2. A request is made to /cas/logout
3. CAS will locate the TGT and will attempt to destroy it, among other things (removing the cookie, etc)
4. In destroying the ticket, CAS will:
o Ask the ticket to expire itself, which will issue SLO callbacks.
o Delete the ticket from the registry

Please note that the behavior described from 2 to 4 in this case is standard case behavior for the /logout endpoint and executes regardless of the ticket registry type.