Home | Code Samples | Software | Networking | Curriculum Vitae (PDF) blue@udel.edu    Phone: (302) 831-7281    Office 212P, The Computing Center
192 S. Chapel St., Newark, DE 19716

The Central Authentication Service (CAS), was developed at Yale University and is currently a Jasig project. It provides enterprise single sign-on service and clients in several different languages. In 2008 while working for the Development office I was writing a web application in Python that needed to make use of UD's implementation of CAS. At the time a simple client for CAS in Python did not exist as I needed it, so I decided to create one. There's probably a much better version of this out there somewhere now, but the code is here if anybody wants to make use of it. Because I submitted this to UD's own CAS guidelines page, I also tried to comment it as best I could. I've been told by other developers at the university writing applications that use CAS that this code is a good reference, no matter what language you're programming in.

# by Fraser Gutteridge, blue@udel.edu
# Created on August 20th, 2008
 
# Small Python script to utilize the University of Delaware's Central
# Authentication Service (CAS).
 
import cgi, urllib
from xml.dom import minidom
 
############################################################
# configuration variables - change these to fit your setup #
############################################################
 
# URL of server running CAS service - currently set for test
CAS_HOST = 'https://mycasservice.testdomain.bleh/cas/'
 
# URL of your server
MY_HOST = 'https://mycasclient.testdomain.bleh'
# path to your service
MY_SERVICE = MY_HOST + 'my-service-path'
 
###############################
# end configuration variables #
###############################
 
# get the URL variables and values
URL_vars = cgi.FieldStorage()
 
# look for the 'ticket' variable
# if it isn't there, we need to redirect
# to the CAS login
if not URL_vars.has_key('ticket'):
 
   # can do this w/ either META tag or 'Location:'
   print """
<html>
<head>
   """
   print('<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=' + CAS_HOST +
         'login?renew=true&service=' + MY_SERVICE + '\">')
   print """
</head>
</html>
   """

else:
 
   # if we did get the ticket, we need to try and validate
   # our service
   vs_params = urllib.urlencode({'ticket': URL_vars['ticket'].value,
                                 'service': MY_SERVICE})
   validate_service = urllib.urlopen(CAS_HOST + "/serviceValidate?%s" % vs_params)
 
   # get the response back and close the object
   vs_response = validate_service.read()
   validate_service.close()
 
   # response is stored as a string but CAS information
   # is actually returned as a well-formed XML doc, so
   # lets use it as that
 
   # parsing returned CAS XML doc using minidom
   CAS_XML = minidom.parseString(vs_response)
 
   # if the service couldn't validate, print error message and stop
   if not CAS_XML.getElementsByTagName('cas:authenticationSuccess'):
 
      print """
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
UD CAS login was not successful. Please try again.
</body>
</html>
      """
 
   else:
 
      # looks like we got in, so pull all the data we need
      # check with your CAS admins for all information available
      # from your CAS service
 
      print """
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
      """
 
      print "<form name=\"CAS\" action=\"" + MY_SERVICE + "/help.html\" method=\"POST\">"
      for info in CAS_XML.firstChild.firstChild.nextSibling.childNodes:
         if info.nodeType == info.ELEMENT_NODE:
            print ("<input type=\"hidden\" name=\"" + info.localName +
                   "\" value=\"" + info.firstChild.data + "\">")
   
      print """
  <script language="javascript">
    document.CAS.submit();
  </script>
  <noscript>
    <input type="submit" value="Click here to use the help form...">
  </noscript>

</form>
</body>
</html>

      """