Source

Django CAS / README

Full commit
Django CAS:

Original Author: Brian Beck <exogen@gmail.com>
Current Maintainer/User: Chris Green <greencm@gmail.com>

Django CAS authentication module for a while, I decided to make a couple improvements.

The biggest improvement is that instead of modifying code in the CAS
module itself to set your CAS address and do things like custom User
field population, all this stuff can now be configured in your
settings file.

Another improvement is that CAS authentication now works for the
bundled admin interface. Since the administration interface does not
account for an authentication backend that doesn't know the user's
password, this makes the login form useless. The CAS module will now
intercept requests to the administration interface and do the proper
authentication routine if necessary, never showing the login form
(which doesn't make sense for CAS). Intercepting requests, you ask?
Yes, that means the CAS module is now middleware. Actually it's
middleware, a couple views, and an authentication backend.  This
authentication backend actually just augments the built-in
authentication backend so both must be enabled even though credentials
from the built-in contrib.auth backend will fail!

Place the django_cas directory in your PYTHONPATH.

Now add it to the middleware and authentication backends in your settings. Make sure you also have the authentication middleware installed. Here's what mine looks like:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_cas.cas.middleware.CASMiddleware',
    'django.middleware.doc.XViewMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django.contrib.cas.backend.CASBackend',
)

You can now configure the CAS module in the same settings file. Here are the possible options, most of which can be safely ignored:

    * CAS_SERVER_URL: This is the only setting you must explicitly define. Set it to the base URL of your CAS source.
    * CAS_POPULATE_USER: A callable or the location of a callable. When a user logs in and is missing name and email attributes in the database, this will be called with their User model instance. Default is None (do nothing).
    * CAS_ADMIN_PREFIX: The URL prefix of the Django administration site. If undefined, the CAS middleware will just check the view being rendered to see if it lives in django.contrib.admin.views. The method is a little evil, but it works.
    * CAS_LOGIN_URL: The URL where you bound django.contrib.cas.views.login. If undefined, assume /accounts/login/.
    * CAS_LOGOUT_URL: The URL where you bound django.contrib.cas.views.logout. If undefined, assume /accounts/logout/.
    * CAS_REDIRECT_URL: Where to send a user after logging in or out if there is no referrer and no next page set. Default is /.
    * CAS_REDIRECT_FIELD_NAME: The name of the GET parameter in which to store the page URL to send the user to after logging in. Default is next.

Need an example? Here's what my CAS settings look like:

CAS_SERVER_URL = 'https://login.example.edu/cas/'
CAS_POPULATE_USER = 'present.utils.populate_user'

And the callable that lives at present.utils.populate_user (notice this code lives in my project instead of tinkering with the CAS module) looks like this:

def populate_user(user):
    try:
        ldap = LDAP()
        person = ldap.filter_one_by(uid=user.username)
    except:
        if not user.email:
            user.email = "%s@case.edu" % user.username
    else:
        # If it succeeds, update their User entry
        user.email = person.mail[0]
        user.first_name = fix_case(person.givenName[0])
        user.last_name = fix_case(person.sn[0])

(LDAP and fix_case also live in my utils module).

Finally, make sure your project knows how to log users in and out by adding these to your URLconf:

(r'^accounts/login/$', 'django.contrib.cas.views.login'),
(r'^accounts/logout/$', 'django.contrib.cas.views.logout'),

Users should now be able to log into your site, and staff into the administration interface, using CAS 1.0.

If you require the use of the @permission_required decorator, there is
a known issue that can cause an infinite loop. You can look at
applying the django/contrib/auth/decorators.py to integrate the two.
There is also a permfail.py that worked with older 0.96 versions of
the django framework.

For more information, see
http://groups.google.com/group/django-developers/browse_thread/thread/8f81ed9644dfc84e