The existing quasi SAML-based single sign out mechanism suffers from both practical and conceptual shortcomings:
- Violates Single Logout Profile specification
- The LogoutRequest message contains an invalid BaseID/NameID/EncryptedID element.
- The POST parameter name for the LogoutRequest is logoutRequest, where it is required to be SAMLRequest.
- The XML message is not encoded per the specification of the SAML HTTP POST binding.
- Back-channel communication interferes with message delivery for clustered/load balanced services.
While 1a and 1b have not been a concern in practice, items 1c and 2 limit the capabilities of single sign-out in CAS. An issue was brought to our attention recently where improper encoding of the LogoutRequest SAML message triggers security components that inspect HTTP requests for attack vectors. The root cause is the presence of "<" and ">" characters signifying XML markup, which would be avoided if the message were encoded per the specification.
Back channel communication is the biggest obstacle to reliable single sign-out in an enterprise environment where CAS services tend to be horizontally scaled for performance and availability.
Using existing standards it is possible to develop a single sign-out mechanism where the user agent is central to message delivery, i.e. front-channel communication, such that single sign-out messages are reliably delivered to services regardless of service architecture (i.e. clustering, load balancing, presence of Web application firewalls). The SOAP HTTP Redirect binding is specifically designed for user agent-mediated communication, and tweaking the existing implementation to leverage this binding should be straightforward. The following sequence diagram provides a helpful overview of the proposed mechanism:
- User requests to log out of CAS by visiting CAS /logout URI.
- The TGT is removed from the ticket registry and returned for examination.
- The list of services accessed during the SSO session is computed from the TGT.
- A data structure comprising the service listing, current index, and slots for per-service logout state is stored under a globally unique key "RelayState". Reusing the TGT ID for the RelayState key is likely the simplest solution.
- For each service in accessed service listing, do the following.
- Send a LogoutRequest message via HTTP Redirect to the service by mentioning it in the Location header of a 302 redirect response. The RelayState parameter MUST be that under which the service listing data structure is stored.
- Client MUST respond with a LogoutResponse via HTTP Redirect, mentioning the CAS /logout URI in the Location of a 302 redirect. The RelayState parameter MUST be the same as that provided in the request, which is consistent with the HTTP Redirect binding specification.
- The CAS server looks up the service listing given the RelayState parameter, records the response, increments the count, and determines the next service.
- The CAS server displays a summary of the communication with services. At a minimum it should display the response from each service: success, fail, indeterminate.
- The server SHOULD have some mechanism for continuation in response to an unreachable client or a client that does not redirect back to the CAS server. One possible mechanism may be sending LogoutRequest messages over HTTP POST (i.e. back channel) for all remaining services after a timeout period elapses.
- The mechanism may be unacceptably slow under some circumstances (e.g. slow links, unresponsive services, large number of services visited) when executed serially. Using AJAX to parallellize message sending may improve performance and provide opportunities for improving behavior for slow or unreachable clients.
- Single Logout Profile, Section 4.4, Profiles for the OASIS Security Assertion Markup Language (SAML) V2.0
- Single Logout Protocol, Section 3.7, Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0
- HTTP Redirect Binding, Section 3.4, Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0
- HTTP POST Binding, Section 3.5, Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0