/Paste-1.7.5.1-py2.7.egg/paste/auth/cas.py

https://github.com/renfers/ageliaco.tracker · Python · 99 lines · 74 code · 10 blank · 15 comment · 11 complexity · 8ad4a6ed3a8f48db799a4c040e04de56 MD5 · raw file

  1. # (c) 2005 Clark C. Evans
  2. # This module is part of the Python Paste Project and is released under
  3. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  4. # This code was written with funding by http://prometheusresearch.com
  5. """
  6. CAS 1.0 Authentication
  7. The Central Authentication System is a straight-forward single sign-on
  8. mechanism developed by Yale University's ITS department. It has since
  9. enjoyed widespread success and is deployed at many major universities
  10. and some corporations.
  11. https://clearinghouse.ja-sig.org/wiki/display/CAS/Home
  12. http://www.yale.edu/tp/auth/usingcasatyale.html
  13. This implementation has the goal of maintaining current path arguments
  14. passed to the system so that it can be used as middleware at any stage
  15. of processing. It has the secondary goal of allowing for other
  16. authentication methods to be used concurrently.
  17. """
  18. import urllib
  19. from paste.request import construct_url
  20. from paste.httpexceptions import HTTPSeeOther, HTTPForbidden
  21. class CASLoginFailure(HTTPForbidden):
  22. """ The exception raised if the authority returns 'no' """
  23. class CASAuthenticate(HTTPSeeOther):
  24. """ The exception raised to authenticate the user """
  25. def AuthCASHandler(application, authority):
  26. """
  27. middleware to implement CAS 1.0 authentication
  28. There are several possible outcomes:
  29. 0. If the REMOTE_USER environment variable is already populated;
  30. then this middleware is a no-op, and the request is passed along
  31. to the application.
  32. 1. If a query argument 'ticket' is found, then an attempt to
  33. validate said ticket /w the authentication service done. If the
  34. ticket is not validated; an 403 'Forbidden' exception is raised.
  35. Otherwise, the REMOTE_USER variable is set with the NetID that
  36. was validated and AUTH_TYPE is set to "cas".
  37. 2. Otherwise, a 303 'See Other' is returned to the client directing
  38. them to login using the CAS service. After logon, the service
  39. will send them back to this same URL, only with a 'ticket' query
  40. argument.
  41. Parameters:
  42. ``authority``
  43. This is a fully-qualified URL to a CAS 1.0 service. The URL
  44. should end with a '/' and have the 'login' and 'validate'
  45. sub-paths as described in the CAS 1.0 documentation.
  46. """
  47. assert authority.endswith("/") and authority.startswith("http")
  48. def cas_application(environ, start_response):
  49. username = environ.get('REMOTE_USER','')
  50. if username:
  51. return application(environ, start_response)
  52. qs = environ.get('QUERY_STRING','').split("&")
  53. if qs and qs[-1].startswith("ticket="):
  54. # assume a response from the authority
  55. ticket = qs.pop().split("=", 1)[1]
  56. environ['QUERY_STRING'] = "&".join(qs)
  57. service = construct_url(environ)
  58. args = urllib.urlencode(
  59. {'service': service,'ticket': ticket})
  60. requrl = authority + "validate?" + args
  61. result = urllib.urlopen(requrl).read().split("\n")
  62. if 'yes' == result[0]:
  63. environ['REMOTE_USER'] = result[1]
  64. environ['AUTH_TYPE'] = 'cas'
  65. return application(environ, start_response)
  66. exce = CASLoginFailure()
  67. else:
  68. service = construct_url(environ)
  69. args = urllib.urlencode({'service': service})
  70. location = authority + "login?" + args
  71. exce = CASAuthenticate(location)
  72. return exce.wsgi_application(environ, start_response)
  73. return cas_application
  74. middleware = AuthCASHandler
  75. __all__ = ['CASLoginFailure', 'CASAuthenticate', 'AuthCASHandler' ]
  76. if '__main__' == __name__:
  77. authority = "https://secure.its.yale.edu/cas/servlet/"
  78. from paste.wsgilib import dump_environ
  79. from paste.httpserver import serve
  80. from paste.httpexceptions import *
  81. serve(HTTPExceptionHandler(
  82. AuthCASHandler(dump_environ, authority)))