Middlebury

CAS

About

Middlebury College uses the Central Authentication Service (CAS) developed by Yale and maintained by Jasig for single-sign-on to our suite of web-based applications.

Supported Protocols

CAS 2.0

Our CAS server supports both standard and proxy-authentication via the CAS 2.0 protocol. The validation response is extended to include user attributes (see below). If your client application does not need proxy-authentication, it is recommended that you use the SAML protocol which includes user-attributes in a standard way.

CAS 2.0 Protocol Extension: Attributes

The CAS 2.0 Protocol deals only with returning a user-identifier on successful authentication and punts on returning any additional information about users. The general practice by many CAS implementers has been to fetch user attributes from an LDAP server based on the identifier returned by CAS. Many other institutions have found this practice to be unacceptable and have modified their CAS servers to return additional attributes with the user response, we are a member of the latter group.

Our CAS server has been updated to return a number of cas:attribute elements alongside the cas:user identifier element. This allows applications to access commonly needed attributes such as group-membership, name, and email address without having to make additional requests from another system. Since virtually every client application that needs to authenticate users also needs to access these attributes, returning them in the CAS response eliminates a number of excess requests and allows applications to know about and rely on only one system.

Unfortunately, many client applications do not natively support these additional attributes and need to be updated to use them. For PHP applications the phpCAS library (version 1.2.0 and later) supports the attribute format we return via its phpCAS::getAttributes() method. If your client application does not look for attributes in the CAS 2.0 response, it will need to be updated to call phpCAS::getAttributes() or a similar process in other environments. Another option is to use the SAML 2.0 protocol to authenticate rather than the CAS 2.0 protocol as the SAML 2.0 protocol includes attributes by default, so clients are more likely to expect to find them in the response.

Finally, if it is not possible to update the CAS authentication module of an application or use the SAML 2.0 protocol, it is possible to fetch user-attributes from our LDAP servers with a few caveats:

  • You will need credentials for reading attributes out of the LDAP server
  • Because groups in our LDAP server (Active Directory) may be members of groups themselves, your application will need to manually traverse the group hierarchy in order to get a full list of groups.
    Example: A class-group does not directly have any members, but rather is a container for three groups (instructors, students, audits) that each directly contain members.
  • We may run multiple LDAP servers in the future to hold information on visitors and other constituent groups. At that time you may encounter users who can authenticate via CAS, but are not listed in our primary LDAP server.

SAML

Our CAS server supports both the SAML 1.1 and SAML 2.0 protocols.

The SAML 1.1 protocol is recommended for all clients that require user attributes and that do not need proxy authentication.

Single Sign Out

At this time our CAS server does not support Single Sign Out.

CASifying applications

In this section you will find instructions for adding CAS support to your web applications.

  • CAS is a service for providing authentication, answering the question: Who is this person?
  • CAS does not provide authorization. It does not answer the question: What can this person do?

General Configuration

The following settings may be asked for when configuring applications to authenticate via CAS.

Data returned by CAS

Valid assumptions

Applications are free to make the following assumptions in relation to CAS.

  • User identifiers are unique - The identifier returned to an application from CAS will always uniquely identify a user.
  • User identifiers are un-changing - Changes in a user's status or name will not change their identifier.
  • The MemberOf (group membership attribute) is authoritative - Applications may use the MemberOf attribute to determine roles and authorizations. The values of this attribute are institutionally defined.

Invalid assumptions

Applications should not make the following assumptions in relation to CAS.

  • Authentication implying authorization - Authentication (and the receipt of a user id) does not imply that a user has any official status in relation to Middlebury College. Anyone can register for a Middlebury_Guest_Account that they can use to log in. Group-membership (MemberOf attribute) or a list of authorized ids should be checked to determine authorization within an application.
  • The user identifier implying meaning - Applications should treat the user identifier as an opaque string with up to 50 characters. No meaning should be inferred by the value of the identifier.
  • Additional attributes exist and have been verified - The MemberOf attribute can be trusted to be authoritative. All other attributes -- such as FirstName, LastName, Email, etc -- may or may not exist and may contain values self-submitted by visitors.

Useful Groups

Every application has its own needs for access and the roles that should be given for various users. Some applications are completely open to public usage, others authorize access to anyone officially associated with the institution, and still others restrict authorization to very limited groups of users. Applications should use the MemberOf attribute to determine membership in groups. Some groups will contain just users that are officially associated with the institution, others will contain just visitors, and still others will contain a mixture of both visitors and institutionally-associated users.

For reference, here are some groups that applications may find useful for common cases:

  • CN=institution,OU=General,OU=Groups,DC=middlebury,DC=edu All officially associated Middlebury people, contains members of the groups below.
  • CN=All Staff,OU=General,OU=Groups,DC=middlebury,DC=edu
  • CN=All Faculty,OU=General,OU=Groups,DC=middlebury,DC=edu
  • CN=students,OU=Students_By_Year,OU=Groups,DC=middlebury,DC=edu
  • CN=All LS People,OU=LS Lists,OU=Groups,DC=middlebury,DC=edu
  • CN=All LS Faculty,OU=LS Lists,OU=Groups,DC=middlebury,DC=edu
  • CN=MIIS Faculty,OU=Groups,DC=middlebury,DC=edu
  • CN=MIIS Staff,OU=Groups,DC=middlebury,DC=edu

Example Authentication Response

Below is an example response from the CAS server on successful authentication. Please note that the order of elements is arbitrary and that all of the valid and invalid assumptions above must be adheared to.

Also note that the cas:attribute elements are non-standard additions to the response (though this addition is in wide use). CAS plugins for systems therefore may not know about attributes and may be expecting to do a subsequent LDAP lookup in order to fetch attributes.

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>q234wd325253</cas:user>
        <cas:attribute name="Login" value="jdoe"/>
        <cas:attribute name="Status" value="Staff"/>
        <cas:attribute name="EMail" value="jdoe@middlebury.edu"/>
        <cas:attribute name="TelephoneNumber" value="802.443.2100"/>
        <cas:attribute name="FirstName" value="John"/>
        <cas:attribute name="Id" value="q234wd325253"/>
        <cas:attribute name="LastName" value="Doe"/>
        <cas:attribute name="MemberOf" value="CN=DFS-LIS-Circulation Services,OU=DFS_Permissions,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=DFS-LIS-LISstaff,OU=DFS_Permissions,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=DFS-LIS,OU=DFS_Permissions,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=DFS Users,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=Student Org Advisors,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=webmkover-platform,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=LIS Liaisons,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=LIS Systems & Infrastructure Cluster,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=district-lis,OU=Staff Districts,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=LIS Educational Services Group,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=All Staff,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=institution,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
        <cas:attribute name="MemberOf" value="CN=HEATUsers,OU=General,OU=Groups,DC=middlebury,DC=edu"/>
    </cas:authenticationSuccess>
</cas:serviceResponse>


Adding CAS support to PHP applications

The best way to enable your PHP application to authenticate against CAS is to use the phpCAS library (version 1.2.0 or later) and the methods contained therein.

Additional documentation about the phpCAS library is available on the CAS wiki.

Step by Step

For web applications running on the development server anvil.middlebury.edu, you may skip steps 1 and 3. In this case, your include path in step 2 will be

<?php require_once "CAS.php"; ?>
  1. Download the latest version of the phpCAS library and unzip it where it can be accessed by your application code.
  2. Include the phpCAS library in your code
    <?php require_once "/path/to/phpCAS/source/CAS.php"; ?>
  3. Optional - Enable debug-mode for testing purposes:
    <?php phpCAS::setDebug(); ?>
  4. Configure and initialize phpCAS:
    <?php phpCAS::client(CAS_VERSION_2_0,'login.middlebury.edu', 443,'/cas/'); ?>
  5. It is preferred to have your application validate the SSL certificate of the CAS server. Our CAS server uses an SSL certificate provided by DigiCert. The Certificate Authority (CA) file to be used is located at: https://login.middlebury.edu/DigiCertCA.crt. Save this file to a place where your application can access it and configure its path in phpCAS:
    <?php phpCAS::setCasServerCACert('/etc/pki/tls/certs/DigiCertCA.crt'); ?>
    The DigiCert certificate may be installed on your machine already. If so, you should be able to use the bundle file:
    <?php phpCAS::setCasServerCACert('/etc/pki/tls/certs/ca-bundle.crt'); ?>
    However, you have problems with the certificate validation (such as your PHP installation not having SSL support), use the following line to skip CAS server certificate validation:
    <?php phpCAS::setNoCasServerValidation(); ?>
  6. Force authentication when a user tries to view the page:
    <?php phpCAS::forceAuthentication(); ?>
  7. Contact one of the CAS administrators (Adam Franco or Ian McBride) with the URL of your application so that they can add it to the list of allowed applications.

Example Usage

Below is an example PHP script that will authenticate against the CAS and print out the user id and attributes.

<?php

require_once "/path/to/phpCAS/source/CAS.php";

// set debug mode
phpCAS::setDebug();

// initialize phpCAS
phpCAS::client(CAS_VERSION_2_0,'login.middlebury.edu', 443,'/cas/');

// Our CAS server uses an DigiCert certificate, the CA file to be used is located at:
// https://login.middlebury.edu/DigiCertCA.crt
phpCAS::setCasServerCACert('/etc/pki/tls/certs/DigiCertCA.crt');

// force CAS authentication
phpCAS::forceAuthentication();

// at this step, the user has been authenticated by the CAS server
// and the user's login name can be read with phpCAS::getUser().

// logout if desired
if (isset($_REQUEST['logout'])) {
phpCAS::logout();
}

// for this test, simply print that the authentication was successful
?>
<html>
<head>
<title>Simple CAS client</title>
</head>
<body>
<h1>Testing CAS</h1>
<h2>Successful Authentication!</h2>
<p>the user's id is <b><?php echo phpCAS::getUser(); ?></b>.</p>
<p>phpCAS version is <b><?php echo phpCAS::getVersion(); ?></b>.</p>
<p><a href="?logout=">Logout</a></p>
<hr/>
<pre>
<?php print_r(phpCAS::getAttributes()); ?>
</pre>
</body>
</html>


Proxy Authentication

In addition to allowing applications to authenticate users, the CAS protocol also supports proxy authentication. Proxy authentication is when a user-facing application (for example, a blog) passes off ("proxies") authentication information to an underlying service (for example, a directory service). The underlying service needs to verify for itself that the user is who they say they are as well as that the application requesting the information is who it says it is. To accomplish this the CAS protocol includes a bit of back and forth to verify the identities of all parties involved.

  1. The user-facing application forwards the user's browser to CAS and includes an HTTPS PGT-callback-URL as a parameter.
  2. After successful authentication, the CAS server tries to validate the SSL certificate of the callback URL. If validation is successful and the application is allowed to proxy, the CAS server will make a GET request to the callback URL with a a proxy-granting-ticket-IOU (PGTIOU) and a proxy-granting-ticket (PGT) as parameters.
  3. CAS forwards the browser back to the application with its service ticket (ST).
  4. The application makes a request to the CAS server to validate its service ticket (ST) and receives back a response with the user id, attributes, and (if a PGT was successfully sent) the PGTIOU.
  5. The application then uses the PGTIOU to locate the proper PGT stored by its callback URL.
  6. The application can then include the PGT in requests to underlying services to obtain priviledged resources.

The CAS Directory is an example of a service that can be accessed by applications via proxy authentication. Here is an example application and callback script that together can access the directory service. Please note that the application also must have its URL added to CAS by the CAS administrators with the 'Allowed to Proxy' flag enabled. As well, the storePGT.php script must live on an HTTPS url with a server certificate that is signed either by the Middlebury College CA or Verisign. See the CAS Directory page for more details on using the directory service.

Below is an example of a basic directory client:

<?php

$name = preg_replace('/[^a-z0-9_-]/i', '', dirname($_SERVER['SCRIPT_NAME']));

session_name($name);

//
// phpCAS proxied proxy
//

// import phpCAS lib
include_once('phpcas/source/CAS.php');

// set debug mode
phpCAS::setDebug();

// initialize phpCAS
phpCAS::proxy(CAS_VERSION_2_0,'login.middlebury.edu', 443,'/cas');

// set the callback URL for the PGT to be sent to. This must be an https url
// whose certificate is trusted by CAS.
phpCAS::setFixedCallbackURL('https://example.middlebury.edu/DirectoryClient/storePGT.php');

// Our CAS server uses a DigiCert certificate, the CA file to be used is located at:
// https://login.middlebury.edu/DigiCertCA.crt
phpCAS::setCasServerCACert('/etc/pki/tls/certs/DigiCertCA.crt');

// force CAS authentication
phpCAS::forceAuthentication();

// at this step, the user has been authenticated by the CAS server
// and the user's login name can be read with phpCAS::getUser().

// moreover, a PGT was retrieved from the CAS server that will
// permit to gain accesses to new services.

$service = 'https://login.middlebury.edu/directory/?action=search_users_by_attributes&LastName=franco&strict=false';

?>
<html>
<head>
<title>phpCAS proxied proxy example</title>
</head>
<body>
<h1>phpCAS proxied proxy example</h1>
<p>the user's login is <b><?php echo phpCAS::getUser(); ?></b>.</p>
<p>Session: (id <?php print session_id(); ?>)</p>
<pre><?php print_r($_SESSION); ?></pre>
<h2>Response from service <?php echo $service; ?></h2><ul><hr>
<?php
flush();
// call a service and change the color depending on the result
if ( phpCAS::serviceWeb($service,$err_code,$output) ) {
echo '<font color="#009900">';
} else {
echo '<font color="#FF0000">';
}
echo "<pre>\n";
echo htmlspecialchars($output);
echo "</pre>";
echo '</font><hr></ul>';
?>
</body>
</html>

And here is the corresponding storePGT.php script:

<?php
$name = preg_replace('/[^a-z0-9_-]/i', '', dirname($_SERVER['SCRIPT_NAME']));

session_name($name);

//
// phpCAS proxied proxy
//

// import phpCAS lib
include_once('phpcas/source/CAS.php');

// set debug mode
phpCAS::setDebug();

// initialize phpCAS
phpCAS::proxy(CAS_VERSION_2_0,'login.middlebury.edu', 443,'/cas');

// Our CAS server uses a DigiCert certificate, the CA file to be used is located at:
// https://login.middlebury.edu/DigiCertCA.crt
phpCAS::setCasServerCACert('/etc/pki/tls/certs/DigiCertCA.crt');

// Run the isAuthenticated() method to store the PGT to a temporary file.
phpCAS::isAuthenticated();

echo "Success";


Supported Applications

Applications currently using CAS

Applications currently being converted to CAS

Powered by MediaWiki