Using CAS with Django – an Update

As I move closer to deploying my application in production, I have been rethinking my implementation of CAS in Django, as outlined in this earlier post,Using CAS with Django. Nothing major, but I don’t like the idea of commenting or uncommenting the code based on the server being used. Here’s what I came up with:

First, I added a new variable to settings.py called USE_CAS. This is set to False by default. Following that, I have some code that determines the server (out of scope for this post) and changes the variable to True if needed.

settings.py

USE_CAS = False

## Check for Production server - the real code is much better than this
if SERVER_ENVIRONMENT == 'Prod':
    USE_CAS = True

Later, I can use that variable to decide whether to execute the CAS specific portions of code:

settings.py

## django_cas settings

if USE_CAS:
    CAS_SERVER_URL = 'https://www.example.com/apps/account/cas/' 
    CAS_VERSION = '2'
    
    AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.ModelBackend',
        'django_cas.backends.CASBackend',
    )
    
    MIDDLEWARE_CLASSES += (
        'django_cas.middleware.CASMiddleware',
    )

## end django_cas settings
urls.py

# django_cas
if settings.USE_CAS:
    urlpatterns = patterns('',
    url(r'^accounts/login/$', 'django_cas.views.login',name='login'),
    url(r'^accounts/logout/$', 'django_cas.views.logout',name='logout'),
                           ) + urlpatterns
                           
# end django_cas

Now, to properly direct the logout link, I’m taking a different approach. My previous example showed how I changed the links on the top right of the page to point to the proper logout link by replacing that section of the admin template in admin/base_site.html. I probably could have passed in the USE_CAS variable in the context and then selectively modified the template, but I instead wanted to simplify the process, not make it more difficult. After searching around a little, I found an unrelated post about using redirects to handle legacy URLs. This worked great, as I was able to redirect both the logout and change password links to the proper destination. Note that the change password functionality is not part of my project, but is provided by the central IT organization that also provides the CAS services.

urls.py

# django_cas
if settings.USE_CAS:
    urlpatterns = patterns('',
    ('^admin/logout/$', 'django.views.generic.simple.redirect_to', 
            {'url': '../../accounts/logout'}),
    ('^admin/password_change/$', 'django.views.generic.simple.redirect_to', 
            {'url': 'https://www.example.com/apps/account/ChangePassword'}),
    url(r'^accounts/login/$', 'django_cas.views.login',name='login'),
    url(r'^accounts/logout/$', 'django_cas.views.logout',name='logout'),
                           ) + urlpatterns
                           
# end django_cas

Pretty slick, don’t you think? Now, I have an easy to maintain setup that will work in any of my development and production environments. Plus, I cut the number of code files affected from 3 to 2, and I have no more commenting to worry about.

I would love to hear how others have solved this or a similar issue. Please leave your comments below.

Comments are closed.