QueryString = Trim(CGI.QUERY_STRING); //strip the ticket off the query string if it exists TicketIndex = FindNoCase( "ticket=", QueryString ); if( TicketIndex GT 1 ) { QueryString = left( QueryString, TicketIndex - 2 ); } else if ( TicketIndex EQ 1 ) { QueryString = ""; } if ( Len(QueryString) GT 0 ) { QueryDelim = "?"; } else { QueryDelim = ""; } if ( CGI.HTTPS EQ "On" ) { HTTPData="https://"; } else { HTTPData="http://"; } return HTTPData & CGI.HTTP_HOST & CGI.SCRIPT_NAME & QueryDelim & QueryString; r_user_id = ""; if ( StructKeyExists(server.cas_cache,cookieHash) ) { cutoff = DateAdd("h", -1*attributes.timeout, now()); if ( DateCompare(server.cas_cache[cookieHash].timestamp,cutoff) gt 0 ) { r_user_id = server.cas_cache[cookieHash].user_id; } else { deleteCacheEntry(cookieHash); } } return r_user_id; cookieExists = checkCookie(arguments.cookieHash); if (cookieExists neq "") { //Delete an existing cookie for this ST for safety deleteCookie(); deleteCacheEntry(cookieExists); } //Assemble the new cookie struct and add to the cache newCookie = StructNew(); newCookie.user_id = user_id; newCookie.timestamp = now(); server.cas_cache[cookiehash] = newCookie; if ( StructKeyExists(server.cas_cache,cookieHash) ) { StructDelete(server.cas_cache,cookieHash); } //set a last cleaned struct to now for either setting or updating the cache lastCleaned = StructNew(); lastCleaned.user_id = ''; lastCleaned.timestamp = now(); //First, retrieve the last cache cleaning timestamp if ( NOT StructKeyExists(server.cas_cache,"CacheLastCleaned") ) { server.cas_cache["CacheLastCleaned"] = lastCleaned; lastCleanedTime = lastCleaned.timestamp; } else { lastCleanedTime = server.cas_cache["CacheLastCleaned"].timestamp; } //get the current cleaning timeout, based on the current time cleaningTimeout = DateAdd("h", -1*attributes.cleanInterval, now()); //Only proceed if the cleaning interval has expired if ( dateCompare(lastCleanedTime,cleaningTimeout) lt 0 ) { //Set the cleaned time to now, avoiding deadlocks StructUpdate(server.cas_cache,"CacheLastCleaned",lastCleaned); //Loop over the cache, deleting expired cookies for (key in server.cas_cache) { if ( key neq "CacheLastCleaned" AND checkCookie(key) eq "" ) { deleteCacheEntry(key); } } } // Ensure the server-level ticket cache is around if ( not isDefined("server.cas_cache") ) { lastCleaned = StructNew(); lastCleaned.user_id = ''; lastCleaned.timestamp = now(); server.cas_cache = StructNew(); server.cas_cache["CacheLastCleaned"] = lastCleaned; } // Validate required invocation parameters if ( not isDefined("Attributes.cas_server") ) { writeOutput('

ERROR

The cas_auth custom tag requires the following parameters to be set:

cas_server
The base url of your CAS server (i.e. https://cas.yourdomain.edu/)
'); abort(); } // Order of processing: // 1. Existence of form POST (SSOut) // 2. Existence of URL ticket parameter (possible because we redirect after authentication sans ticket) // 3. Existence of CF_CAS cookie // 4. Redirect to CAS // Single Sign Out processing if ( isDefined("Caller.Form.LOGOUTREQUEST") ){ try { XMLResponse = xmlParse(Caller.Form.LOGOUTREQUEST); SearchResults = XmlSearch(XMLResponse,"samlp:LogoutRequest/samlp:SessionIndex"); } catch (Exception e) { SearchResults = ""; } if ( not ArrayIsEmpty(SearchResults) ) { // Valid Logout Request : delete Cookie if exists cookieHash = hash(SearchResults[1].XmlText,"MD5"); if( checkCookie(cookieHash) neq "") { // this deletion is only of active Cache entries deleteCacheEntry(cookieHash); } } } if ( isDefined("URL.ticket") ) { // Coming back from CAS authentication : assemble validation url and validate ValidationURL = Attributes.cas_server & "serviceValidate?ticket=" & URL.ticket & "&" & "service=" & urlencodedformat( getCleanURL() ); // clear the cache of expired entries before validating cleanCache(); // Validate try { HTTPResult = cfhttp(ValidationURL); XMLResponse = xmlParse(cfhttp.FileContent); SearchResults = XmlSearch(XMLResponse,"cas:serviceResponse/cas:authenticationSuccess/cas:user"); } catch (Exception e) { SearchResults = ""; } if ( not ArrayIsEmpty(SearchResults) ) { // Validated : set up the cookie and redirect with the ticket stripped cookieHash = hash(URL.ticket,"MD5"); setCookie(cookieHash,SearchResults[1].XmlText); redirect( getCleanURL() ); } else { // Invalid : redirect to CAS CASURL = Attributes.cas_server & "login?" & "service=" & urlencodedformat( getCleanURL() ); redirect( CASURL ); } } else if ( isDefined("Cookie.CF_CAS") ) { // Check cookie value against cache AuthUser = checkCookie(Cookie.CF_CAS); if( AuthUser neq "") { Request.AuthUser = AuthUser; } else { deleteCookie(Cookie.CF_CAS); //redirect to CAS CASURL = Attributes.cas_server & "login?" & "service=" & urlencodedformat( getCleanURL() ); redirect( CASURL ); } } else { // Not CAS authenticated yet : assemble CAS url and redirect CASURL = Attributes.cas_server & "login?" & "service=" & urlencodedformat( getCleanURL() ); redirect( CASURL ); }