Shawn CAS and SAML

SAML-compatible CAS

This document was produced by Shawn Bayern and shared on the cas@tp discussion list.

Qui melius probat, melius habet.
("He who proves the most holds the most.")

Introduction

The Security Assertion Markup Language (SAML) describes a document and protocol framework by which security assertions (such as assertions about a prior act of authentication) can be exchanged. The model underlying Yale's Central Authentication Service (CAS) is compatible with SAML; this document explains how to conduct CAS authentications (including n-tier proxy authentications) using SAML queries and assertions.

One-tier authentication and single sign-on

At its simplest, CAS concerns authentication at a single application tier: a web application may use CAS to authenticate its interactive user in order, typically, to initialize a session using its own session semantics. The one-tier CAS protocol is well understood; here, I describe how to conduct this authentication by way of SAML. It is important to note that SAML is general enough to allow a variety of specific forms of interaction; this document describes one concrete mechanism. While I believe the proposed model is straightforward and reasonably parsimonious, it's by no means the only way to incorporate SAML into CAS.

The initial steps in a SAML-based CAS authentication match the traditional CAS protocol. Initially, a user contacts a web application, and because this application has no existing session with the user, it redirects the user to CAS in order to request strong authentication. Following this redirection, the user's browser contacts CAS and conducts a primary authentication with CAS, at which point CAS redirects the user back to the service that requested authentication, supplying information in the query string sufficient for the application to verify the authentication.

You might wonder why I don't make an effort to incorporate SAML into this initial step of the protocol. SAML is designed to convey assertions about security; in the realm of authentication, such assertions involve prior acts of authentication. For instance, section 3.3.3 of the SAML specification, which describes a SAML query embodied in an <AuthenticationQuery> element, gives the following warning to SAML implementations:

The <AuthenticationQuery> MAY NOT be used as a request for a new authentication using credentials provided in the request. The <AuthenticationQuery> is a request for statements about authentication acts which have occurred in a previous interaction between the indicated principal and the Authentication Authority.

Furthermore, the nature of CAS yields little advantage in doing attempting to accommodate SAML in this initial step; for this step, the user's browser must be involved, and browsers (so far) have no knowledge of SAML. Thus, as in CAS 1.0 and CAS 2.0, we inform CAS that an authentication is needed by way of a simple HTTP redirect, and CAS informs applications that an authentication assertion is available by way of a correspondent redirect.

In SAML, there are two ways of requesting information about a prior act of authentication. A party can submit an open-ended query or can ask for an assertion based on an ID or an artifact, the latter of which has a format under the application's control. While SAML lets implementations define their own query types and would thus allow for the possibility of a custom CAS query, there seems to be no advantage to doing so. A CAS authentication is already uniquely identified by an artifact, so it is both secure and appropriate to use this artifact.

This precise methodology is straightforward. A web application, having received an opaque ticket from the incoming HTTP request (via its ticket parameter), marshals a SAML request to be sent using SOAP, over HTTPS, to the CAS server. The application contacts CAS over a well-known URL and authenticates CAS using CAS's SSL certificate (applying rules at least as restrictive as a common browser's, to prevent spoofing of CAS). Thus, no XML Signatures are necessary; the underlying channel is trusted. Over this secure channel, the application sends a SAML request of the following form:

Listing 1
  <Request
    RequestID="..."
    MajorVersion="1"
    MinorVersion="0"
    IssueInstant="...
  >
    <AssertionArtifact>opaque ticket string</AssertionArtifact>

  </Request>

When CAS recognizes the opaque ticket string sent within this request, it produces a response containing an appropriate assertion, along with supplemental information that the application will need to ensure that the ticket was intended for it and not for another application:

Listing 2
Listing 2

  <Response>
    <Status>
      <StatusCode Value="Success"/>;
    </Status>
    <Assertion
      MajorVersion="1"
      MinorVersion="0"
      AssertionID="..."
      Issuer="URI for CAS login page"
      IssueInstant="date of response, not of TGC"
    >
      <Conditions>
        <AudienceRestrictionCondition>
          <Audience>service URI associated with ticket</Audience>

        </AudienceRestrictionCondition>
      </Conditions>
      <AuthenticationStatement>
        <Subject>
          <NameIdentifier>subject name</NameIdentifier>

        </Subject>
      </AuthenticationStatement>
    </Assertion>
  </Response>

Unlike the non-SAML CAS protocol, confirmation of the assocation between a ticket and a service is the responsibility of the web application, not of CAS.
Proxiable credentials under CAS 2.0

SAML can also accommodate proxiable credentials, as supported by the CAS 2.0 model. There are three major related to proxying:

  1. Secure acquisition of a proxy-granting ticket (PGT)
  2. Secure acquisition of individual-use proxy tickets
  3. The protocol underlying the use of proxy tickets

Step 3 represents the most appropriate use of SAML, though SAML must accommodate step 1 given that secure PGT acquisition relies on the same secure channel by which authentication assertions are exchanged. This document does not address step 2, for SAML is not specifically intended for ticket acquisition; it is designed to relay assertions, and while a proxy ticket embodies an assertion (used in step 3), its acquisition (step 2) represents a service-level action (with side-effects).

To acquire a PGT using CAS 2.0's basic model, an application must authenticate itself to CAS. Under the basic CAS 2.0 model, this authentication is conducted by virtue of a callback URL; however, this complicates the model, so I will describe an alternative approach more appropriate for SAML.

This approach is straightforward. To authenticate itself to CAS when sending the request from listing 1, the application supplies an XML Signature using the <Assertion> element's <Signature<; subelement. If it is satisfied with the application's authenticity, CAS includes an <AttributeStatement> in the assertion contained in its response. This statement has the following format:

Listing 3
  <AttributeStatement>
    <Subject>
      <NameIdentifier>subject name</NameIdentifier>

    </Subject>
    <Attribute AttributeNamespace="http://www.yale.edu/cas"
                  AttributeName="pgt">
      <AttributeValue>PGT value</AttributeValue>
    </Attribute>
  </AttributeStatement>

Once a proxy has used the PGT acquired in this statement to generate a PT (again, using an out-of-band mechanism that does not necessarily use SAML), it supplies a SAML document to its target back-end service. (It could also simply provide the ticket as a query parameter, just as in the current model; however, using SAML arguably makes it easier for a back-end service to use multiple authentication schemes.) This SAML document contains the following assertion:

Listing 4
  <Assertion
    MajorVersion="1"
    MinorVersion="0"
    AssertionID="..."
    Issuer="URI for application service"
    IssueInstant="date of assertion, not of PGT"
  >
    <AuthenticationStatement>
      <Subject>
        <NameIdentifier>subject name</NameIdentifier>

      </Subject>
      <SubjectConfirmation>
        <ConfirmationMethod>http://www.yale.edu/cas/proxy</ConfirmationMethod>

        <SubjectConfirmationData>proxy ticket</SubjectConfirmationData>

      </SubjectConfirmation>
    </AuthenticationStatement>
  </Assertion>

Note that this is a potentially baseless, bold assertion; it is not trusted. The authentication of the subject is contingent upon validation of the proxy ticket supplied in the <SubjectConfirmation> element.