Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

...

Table of Contents
maxLevel3
excludeTable of Contents

Overview

UH Login (CAS) is available for University of Hawaiʻi (UH) Web site developers to authenticate users with their UH username and password. It alleviates the problem of having to develop a user authentication system as part of the Web-enabled application (web application) development. It also provides increased security for users by not allowing Web applications to handle their passwords (often using insecure means such as sending it in the clear or unnecessarily storing it).

...

Info
titleThe UH Web Login Service is provided via Apereo's Central Authentication Service (CAS).

Currently UH Login is running CAS version 6.3.5.

Please refer to Apereo documentation for authoritative references for CAS client integration and the CAS protocol. The CAS Community mailing list and archives are also valuable sources of information and support.

Additional  info:

...

Before You Register Your Application URL …

Before you register your application URL there are a few details to first consider:

  1. Will authentication include the release of attributes to your application?
    1. If yes, UH Data Governance guidelines apply.  For each unique application you must submit a separate request.  What that means is that you cannot register a single URL and host multiple applications under it.  
  2. Is your application hosted on a non-UH server?
    1. If yes, your request may be subject to the UH Data Sharing Request process. Please send an inquiry to datagov@hawaii.edu or call (808) 956-7487.

...

Register Your Application URL

For security purposes, application URLs must be registered in order to prevent unauthorized use.

...

Web Login process

Web applications registered for UH Login use a link or redirect from their main page to the secure HTML CAS form.

To Authenticate Users

  • A user enters their UH username and password on the UH Login page.
  • After submission, the Web Login Service redirects the user back to your web application along with a service ticket provided by the Web Login Service.
  • Your web application then requests that UH Login validate this ticket.
    • If the user supplied the correct authentication credentials (username/password), UH Login will return a success response to your web application.
    • Otherwise, a failure response is returned.

...

Note
titleCAUTION

After UH Login redirects the user back to your app and you have validated the service ticket, redirect the user to an URL that does not include the service ticket. This reduces the risk of the user bookmarking a URL containing a service ticket. A bookmarked URL containing a service ticket is a problem because the CAS software isn't on guard for this and it results in a looping problem that sends the user back and forth between your application and UH Login, or it may immediately return an unsuccessful authentication result despite the user having provided the correct user password.

...

...

Conventions & Definitions

  • "Client" refers to the end user and/or the web browser.
  • "Server" refers to UH Login (CAS).
  • "Service" refers to the application the client is trying to access (i.e., your application).
    • "TARGET" for samlValidate
  • <LF> is a bare line feed (ASCII value 0x0a).

...

...

CAS URIs

URIs for CAS use the hostname followed by /cas and ended with the desired service. In the examples that follow, substitute the following for $WEBLOGIN-HOST for the appropriate environment.

  • Production
    • https://authn.hawaii.edu/
  • Test
    • https://cas-test.its.hawaii.edu/ (testing does not require registration of your URL)
  • Future Test
    • https://cas-future-test.its.hawaii.edu/
  • Deprecated Production
    • cas-deprecated.its.hawaii.edu/


Info
titleTest vs. Production, what's the difference?

The primary difference between the Test and Production environments is the source of credentials used for authentication and attributes. The production Web Login instance uses production LDAP, whereas the test Web Login instance uses our test LDAP instance. Data in the test LDAP instance generally represents a (somewhat stale) snapshot of the production LDAP. Developers should verify that the credentials they wish to test are available in test LDAP.

The login page presented to the user in the test environment is also conspicuously identified as being "Not intended for normal use" and a "test-env".

...

Info
titleCAS clients

Note that CAS clients are available that handle many of the login and ticket validation details for you. If your development can make use of one of the available CAS clients (eg, Java, PHP) you will probably want to take advantage of them rather than trying to reinvent the wheel.

...

Log in Securely

...

/login

To have a user login securely put a link on your main page to the "login securely" URL with a request parameter named service and having a value that is the Service URL (i.e., the URL of the main page or a page that will be able to handle an HTTP request with a parameter). This link should be labeled with something like "Login Securely" to establish in your user's mind that the password will not be seen by your application and is handled securely. See the next section on ticket validation for information about how your application finds out the username.

...

Info
titleNotes
  1. The service/target URL must be a real URL. For example, most Web servers have a default page that is returned when you request a URL that ends with a forward slash character, "/". This often results in redirects to index.html, index.htm, or index.jsp while others may use default.htm, default.asp, or something similar.
  2. Since the Service URL is passed as the value of a query parameter, it should be URL-escaped to ensure proper interpretation by UH Login. Please refer to Section 2 and Appendix A of RFC 3986 for details.

...

...

Ticket Validation (

...

CAS protocol 1.0

...

, AuthN, simple text response)

/validate

This section describes how your Web application finds out the username of a user that has successfully logged in.

...

  • Here's an example of the URL used by UH Login to redirect the request back to the Web site (with a sample ticket):

    No Format
    https://myserver/myapp?ticket=ST-3-8tkkJbPThesE1cZjVVtc
    


  • The server-side processing of your Service URL must validate the extracted authentication token by sending an HTTP GET request with the following parameters:

    No Format
    service=<Service URL>
    ticket=<service ticket>


  • Using your URL with ticket, send your request to UH Login:

    No Format
    https://$WEBLOGIN-HOST/cas/validate?service=https://myserver/myapp&ticket=ST-95-a1kjb6g4Tcdeh17vfy6g
    


    Info

    Append &renew=true to disallow SSO.


  • After validating the service ticket, UH Login will return a text document indicating success or failure.

    Code Block
    xml
    xml
    titleOn ticket validation success:
    yes<LF>
    username<LF>
    


    Code Block
    xml
    xml
    titleOn ticket validation failure:
    no<LF>
    <LF>
    

...


...

Ticket Validation (

...

CAS protocol 2.0, AuthN, XML response)

...

/serviceValidate

This section describes how your Web application finds out the username of a user that has successfully logged in.

...

  • Here's an example of the URL used by UH Login to redirect the request back to the Web site (with a sample ticket):

    No Format
    https://myserver.example.edu/myapp?ticket=ST-7655-K6dyN9ystYwdOZynSnak-cas


  • The server-side processing of your Service URL must validate the extracted authentication token by sending an HTTP GET request with the following parameters:

    No Format
    service=<Service URL>
    ticket=<service ticket>
    


  • Using your URL with ticket, send your request to UH Login:

    No Format
    https://$WEBLOGIN-HOST/cas/serviceValidate?service=https://myserver.example.edu/myapp&ticket=ST-7655-K6dyN9ystYwdOZynSnak-cas


    Info

    Append &renew=true to disallow SSO.


  • After validating the service ticket, UH Login will return an XML-fragment indicating success or failure.

    Code Block
    xml
    xml
    titleOn ticket validation success:
    <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
        <cas:authenticationSuccess>
            <cas:user>joebogus</cas:user>
            </cas:authenticationSuccess>
    </cas:serviceResponse> 


    Code Block
    xml
    xml
    titleOn ticket validation failure:
    <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
        <cas:authenticationFailure code="INVALID_TICKET">
            Ticket ST-7655-K6dyN9ysFOOdOZynSnak-cas not recognized
        </cas:authenticationFailure>
    </cas:serviceResponse>


    Info
    titleError codes

    The following values may be used as the "code" attribute of authentication failure responses.

    • INVALID_REQUEST
      • not all of the required request parameters were present
    • INVALID_TICKET
      • the ticket provided was not valid, or the ticket did not come from an initial login and "renew" was set on validation. The body of the <cas:authenticationFailure> block of the XML response SHOULD describe the exact details.
    • INVALID_SERVICE
      • the ticket provided was valid, but the service specified did not match the service associated with the ticket. CAS MUST invalidate the ticket and disallow future validation of that same ticket.
    • INTERNAL_ERROR
      • an internal error occurred during ticket validation

...

...


Ticket Validation (

...

CAS protocol 3.0, AuthN with attributes, SAML response):

/samlValidate

This section describes how your Web application determines the username and possibly additional attributes for a user that has successfully logged in.

...

Note
titleFERPA laws may apply!

Information about students must be handled carefully and in accordance with University of Hawai?i data governance policies. FERPA laws constrain what may be published about students. Please check with your Admissions and Records Office for details.

...

Logging Out (SLO)

...

/logout

Web applications that login a user must handle their own session state and should offer the user the ability to log out of their session. Without the logout service provided by CAS, a user returning to the web application's Service URL, will be automatically logged back in because of the ticket-granting cookie also provided by CAS stored by the client. This is a single sign-on feature across web applications that use UH Login. There are two basic ways to "log out"; logout from application and UH Login single sign-on or logout from application and force re-authentication to UH Login.

...

  • url (DISABLED)

    Note

    Although Aperero's CAS protocol documentation describes the use the the url parameter, the Aperero developers have disabled it in recent versions of CAS to prevent potential abuse. Their explanation of the situation may be found in this thread from the cas-users mailing list. The url parameter defined in the former CAS 2.0 specification is not a valid parameter in CAS 3.0 anymore. CAS Servers MUST ignore given url parameters.


Examples
  • To logout a user and prevent her from automatically logging back into a Web application, the Web application can forward the user to the Logout URL of UH Login. That URL will destroy the ticket-granting cookie that enables the single sign-on feature and gives the user a page that informs them that they have logged out of UH Login.

    No Format
    https://$WEBLOGIN-HOST/cas/logout
    


  • To logout a user and prevent her from automatically logging back into a Web application, the Web application can forward the user to the Logout URL of UH Login. That URL will destroy the ticket-granting cookie that enables the single sign-on feature and redirect the user to the URL identified by the service parameter.

    No Format
    https://$WEBLOGIN-HOST/cas/logout?service=https://myserver/myapp
    


    Info

    The URL provided by the service parameter must be registered to use UH Login.


Note
titleSLO is not enabled
Because SLO may affect other applications using SSO[*], it has been disabled as of the implementation of CAS 6.3.5.

[*] From the CAS documentation for Single Logout (SLO):

When a CAS session ends, it notifies each of the services that the SSO session is no longer valid, and that relying parties need to invalidate their own session. Remember that the callback submitted to each CAS-protected application is a notification; nothing more. It is theresponsibility of the applicationto intercept that notification and properly destroy the user authentication session, either manually, via a specific endpoint or more commonly via a CAS client library that supports SLO.

Also note that since SLO is a global event, all applications that have an authentication record with CAS will by default be contacted, and this may disrupt user experience negatively if those applications are individually distinct from each other. As an example, if user has logged into a portal application and an email application, logging out of one through SLO will also destroy the user session in the other which could mean data loss if the application is not carefully managing its session and user activity.

...


Access Control

It is every developer's responsibility to perform any necessary access control (authorization, AuthZ) after a user has logged on to their Web site. This is may be done by using information as attributes for the user. The affiliation, campus, or campus affiliation data should be enough to filter out unauthorized users. Alternatively, you choose explicitly may allow or disallow by username. Ultimately, it is up to each developer to determine how to implement access controls based on available information.

...

...

Sample Clients

...

Java client

Aperero provides an example of SAML 1.1 Ticket Validation Filter.

...

Note

Apereo has taken over CAS from JASIG. The current version of the CAS client may be found here:

To use this client, as with the SAML 1.1 Ticket Validation Filter above, you may need the following jar files:

  • cas-client-core
  • cas-client-support-saml
  • commons-codec
  • commons-logging
  • joda-time
  • log4j
  • opensaml
  • slf4j-api
  • xmlsec

...

UH CAS Demo in Java

UH ITS' own Frank Duckart wrote the following CAS demo using Java and Servlets:

...

Probably not a great idea, but it is also possible to create a CAS client login using JSP only:
Project Repo:  https://github.com/fduckart/uh-jsp-casdemo

...

...

phpCAS client

The phpCAS module is a PHP library that interacts with CAS and allows you to work with user and authentication objects. It also allows for attribute release. The latest phpCAS version may be obtained from the phpCAS Github page. Documentation for phpCAS can be found here.

...

Expand
titleClick to expand: Example PHP code to retain CAS3 CAS authentication across multiple pages

To use CAS across multiple pages, there are two ways to go about it:

The first is to include your phpcas-test.php file at the top of each page. This serves to activate the phpCAS client and will determine if the user has authenticated or not. You can modify your phpcas-test.php file by first checking phpCAS::isAuthenticated() which returns a boolean true or false; if false you can forceAuthentication().

The second is if you intend to use custom session variables across your pages. phpCAS has its own session management values that may interfere with whatever you're doing, so the solution I came up with was storing those CAS values into my app's session variables.

Please note that all examples provided here are extremely condensed, as I am only attempting to demonstrate how one can retain CAS session values along with app-specific session values. As such they should be treated more like pseudocode or an algorithm.

Code Block
titleindex.php
==========================================
index.php (summarized)
This page authenticates the user to my application.  Here I check if the user
is authenticated, and if so, I capture the CAS3CAS session values and user
attributes.
==========================================
<?php

include_once( "../../lib/cas3cas.class.inc.php" )  
// This file is similar to the phpcas-test.php example
// The inclusion of this file activates the phpCAS client, and can
// trigger the authentication of the user if they're not logged in.
// My cas3cas.class.inc.php file is below this example.

// Display session values, to double-check what we have
// The value of $DEBUG is set in my app's configuration file.
// You will notice that the session id and name are set by CAS3.
if ( $DEBUG ) {
    if ( isset( $_SESSION ) ) {
        print "<p />SESSION values set<br />";
        print "Session ID: " . session_id() . "<br />";
        print "Session Name: " . session_name(). "<br />";
        print_r( $_SESSION );
        print "<p />";
    }
}

// Save the attributes
$cas_attributes = array();
foreach ( phpCAS::getAttributes() as $key => $value ) {
    $cas_attributes[$key] = $value;
    $DEBUG && print "phpCAS attribute: $key, Value: $value<br />";
}

// Save the token
$cas_token = session_id();

<!-- HTML form to log user into my application.  I've cut out elements like -->
<!-- the text fields  for username and password entry to focus on CAS3 session -->
<!-- Here, I am submitting the user attributes as hidden fields to the -->
<!-- next page that does the app authentication -->
<form action="app_authentication.php" name="logging_in" method="POST">
    <input type="hidden" name="state" value="cas3cas_authenticated" />
    <?php
    foreach ( $cas_attributes as $name => $attribute ) {
        if ( ! is_array($attribute) ) {
            print '<input type="hidden" name="cas_attributes['.$name.']" value="'.$attribute.'" />';
        }
        else {
            // Some CAS3CAS user attributes are multi-valued.
            foreach ( attribute as $sub_name => $sub_attr ) {
                print '<input type="hidden" name="cas_attributes['.$name.']['.$sub_name.']" value="'.$sub_attr.'" />';
            }
        }
    }
    ?>
    <input type="hidden" name="cas_token" value="<?php print $cas_token; ?>" />
</form>
?>


Code Block
titlecas3cas.class.inc.php
==========================================
cas3cas.class.inc.php
simplified version
==========================================
<?php
require_once "PHPCAS_CONFIG.php";       // this is my config file
require_once $phpcas_path . "CAS.php";  // import phpCAS

phpCAS::setDebug( "/filepath/to/where/i/store/app/logs/cas_debug.log" );
phpCAS::client( SAML_VERSION_1_1, $cas_host, $cas_port, $cas_context, $client_service_name );
phpCAS::setCasServerCACert( $cas_server_ca_cert_path );
phpCAS::handleLogoutRequests( TRUE, $cas_real_hosts );

// If the user isn't authenticated, force authentication
// Here is where we determine if a user has logged in via CAS3CAS
if ( ! phpCAS::isAuthenticated() ) {
    phpCAS::forceAuthentication();
}

if ( isset( $_GET['logout'] ) ) {
    phpCAS::logout();
}
?>


Code Block
titleapp_authentication.php
==========================================
app_authentication.php
This page just handles authenticating my application, as users have passwords
that are not the same as their UH account passwords.
==========================================
<?php

// IMPORTANT!
// Note that I do not include cas3cas.class.inc.php in this page!  If I did,
// phpCAS removes my app's session in order to use its own, and I end up losing
// the user-submitted form in the same process.

// Check if we have the POSTed "state" value of "cas3cas_authenticated" from index.php
if ( (! isset( $_POST['state']) ) || ($_POST['state'] != 'cas3cas_authenticated') ) {
    header( "Location: index.php?error=unauthenticated" );
    exit();
}

// Grab the username, app password, and CAS values
$entered_username   = $_POST[ 'username' ];
$entered_password   = $_POST[ 'password' ];
$cas_attributes     = $_POST[ 'cas_attributes' ];
$cas_token          = $_POST[ 'cas_token' ];

// Start a new session (non CAS session)
session_name( $PHP_SESS_ID );  // This is set in my app's config file so I can reuse and recall anywhere
if ( ! session_start() ) {
    die( "Could not start non-CAS session!" );
}

// Debugging statements, to ensure the values and constants are what I expect them to be.
// Note here that the session id and name should be values that I just set.
$DEBUG && print "
    <p />
    Session Name: ".session_name()."<br />
    Session ID: ".session_id()."<br />
    APP HOST: $APP_HOST<br />
    LDAP: $LDAP_HOST<br />
    Location: ".$_SERVER['PHP_SELF']."
    <p />
";

// Assume I have code to validate the user's name and password.
// Next I store the CAS attributes and token into my currently-active session ($PHP_SESS_ID)
if ( $user_validated ) {
    $_SESSION[ $CAS_ATTRIBUTES  ] = $cas_attributes;
    $_SESSION[ $CAS_TOKEN       ] = $cas_token;
}
?>


Code Block
titleother_pages.php
==========================================
all other pages in my application
Now that I have stored the CAS3CAS token and attributes, I can access them
in the rest of my application.
==========================================
<?php

// I still do not include the cas3cas.class.inc.php page

# Start a new session (non CAS session)
session_name( $PHPSESSID );
if ( (! isset( $_SESSION)) || (! $_SESSION) ) {
    if ( ! session_start() ) {
        die( "Cannot start non-CAS session!");
    }
}

// Here I check that the user has a CAS3CAS token (which was set in app_authentication.php)
if ( (! isset( $_SESSION[$CAS_TOKEN] )) || ($_SESSION[$CAS_TOKEN] == $EMPTY_STR) ) {
    $file->write_log_file( "Unauthenticated access to ".$_SERVER['PHP_SELF'], $LOG_DIR.$LOG_WEBLOG );
    header( "Location: index.php?error=unauthenticated" ); // index.php has an error-handler.
    exit();
}

$cas_attributes         = $_SESSION[ $CAS_ATTRIBUTES ];
$uh_username            = $cas_attributes[ $UID ];
$uh_number              = $cas_attributes[ $UHUUID ];

// session id and name should still be the values I set, not CAS3CAS's values.
// You could also include the CAS3CAS values in this debug statement if you
// wanted to verify retention and accuracy.
$DEBUG && print "
    <p />
    Session Name: ".session_name()."<br />
    Session ID: ".session_id()."<br />
    APP HOST: $APP_HOST<br />
    LDAP: $LDAP_HOST<br />
    USER: $uh_username<br />
    UHUUID: $uh_number<br />
    Location: ".$_SERVER['PHP_SELF']."
    <p />
";
?>


...

No Format
Array ( [0] => yes [1] => jschmidt [2] => )

...

cURL client (no attributes requested)

Below is a PHP script using cURL to establish a connection with the CAS server.

...

Expand
titleClick to expand: cas_test.php


Code Block
<?php
# Test CAS URLs
$CAS_LOGIN_URI      = "https://$WEBLOGIN-HOST/cas/login";
$CAS_VALIDATE_URI   = "https://$WEBLOGIN-HOST/cas/validate";
$CAS_LOGOUT_URI     = "https://$WEBLOGIN-HOST/cas/logout";

$single_signon = TRUE;

# Here is where we check if the user has authenticated.  If we cannot find a ticket,
# redirect the user to the CAS login page.
if ( ! isset($_GET["ticket"]) )
{
    $location = "Location: ".$CAS_LOGIN_URI."?service=".urlencode($_SERVER["SCRIPT_URI"]);

    # If we haven't enabled single sign-on, the user has to renew each time.
    if ( ! $single_signon )
    {
        $location = $location."&renew=true";
    }

    header($location);
    exit();
}
else
{
    # Initialize our CURL session with the CAS validation URL.  Supply the server script and ticket.
    $validate_string    = $CAS_VALIDATE_URI."?service=".urlencode($_SERVER["SCRIPT_URI"])."&ticket=".$_GET["ticket"];

    $ch = curl_init($validate_string);

    # set the option to return the results
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $cas_return = explode("\n", curl_exec($ch));

    # This dumps out the return values from our cURL request.  Later we check whether or not the user successfully authenticated.
    echo "CAS return via cURL: ";
    print_r($cas_return);
    echo "<br />";

    if ( $cas_return[0] == "yes" )
    {
        echo "User successfully authenticated via CAS<br />";
        for ( $i=0; $i<count($cas_return); $i++ )
        {
            echo "Cas Return #$i: ".$cas_return[$i]."<br />";
        }
    }
    else
    {
        echo "User not validated<br />";
    }
}

?>

...


...

Spring Security CAS Authentication

...

...

Frequently Asked Questions (FAQ)

Why does my site automatically login a returning user after they logout of their session with my site?

...

A future enhancement could make single sign-on an option for the user so the default will be no single sign-on. If the user chooses to enable single sign-on when authenticating to UH Login, only those apps that don't use the renew parameter will permit single sign-on if the user doesn't logout via the Logout URL from a previously visited app.

Why can't I login successfully to the CAS test environment?

There are several reasons for this and one or both may be applicable:

  1. Currently you need to use a UH VPN to access CAS test.  (not a requirement for production CAS, nor will it ever be)
  2. CAS test points to a test LDAP instance that may not have your current password.  Send an email to the IAM team to request a "password sync" if needed.

Can anyone use my Web site?

...

Since this feature is not compatible with our existing business rules, IAM will be disabling this feature during the 2014 calendar year.

...

Troubleshooting

Info
Often the best place to start if you encounter errors, is a review of your logs for indications as to the nature of the problem. This will often yield productive keywords or strings that may be useful in a search or requests for technical support.

...

Application Not Authorized to Use UH Login

Problem:

Your application cannot successfully authentication against CAS.

Example error message:

Panel

The application you attempted to authenticate to is not authorized to use UH Login.


Solutions:

Expand


Panel
  • If you have requested attributes, make sure you are using https.
  • Check that the URL matches the URL specified in your original CAS URL registration request.
    • Common errors
      • Adding or leaving out "www" not in registered registered URL
      • Using "http" as the protocol rather than "https"


...

Reference: CAS Users mailing list thread on time synchronization

...

...

Technical Support

There is an active UH community of developers and a good chance that at least one of them has experience with your scenario.  It is well worth joining this community's email list if you've not already done so.  For details, visit App Developers Forum page.  Note that the ITS Identity and Access Management team also participates on this list.