views:

196

answers:

3

Need to integrate Django with an existing authentication system. That system has it's own database, API, login/logout,edit profile web pages and cookie.

(I may have to add a few additional profile fields stored/updated locally)

What's the proper approach to substitute the out-of-the-box authentication in Django?

A: 

This depends on how you want to handle the problem. If you don't need to keep the existing system running, your best bet is to import their data into the django project.

If the authentication system must stay in tact, you might have to write a wrapper for django.auth. I've done this in the past using SQLAlchemy http://www.sqlalchemy.org to integrate to the external database.

It might be helpful to take a look at the Django 1.2 multi-db support http://djangoadvent.com/1.2/multiple-database-support

In either case I'd try to get the user information into django.auth rather than to write your own authentication system.

digitaldreamer
Taking over the existing system is not an option at all. Integration is what's needed. Imagine a corporate environment with multiple projects, teams, etc.
pq
I've handled this in the past by talking to the other DB through SQLAlchemy. It wasn't a very robust system, and they were silly enough to leave all passwords in plain text so it was relatively easy to create a new django user and authenticate them against the external system.
digitaldreamer
talking directly to the other db is not an option. there is an existing API for this.
pq
You can create new django user if you detect that they already exist in the external system and haven't already created a user for them. You can then run the API to check their authentication. If they a successfully authenticated then you can manually log them in: http://docs.djangoproject.com/en/dev/topics/auth/#how-to-log-a-user-in
digitaldreamer
+2  A: 

I've created a custom authentication backend when I've had to do something similar to what you have to do. See: http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend

In the authenticate function you call your api to authenticate the user, and then map them to a django.contrib.auth.model.User object on some primary key, like username for example. If the primary key is something other than username I usually create a mapping object, or put it into the profile object for the project.

dar
So, IIUC, this means using the API only but none of the (login,update_profile, etc.) pages which that login system comes with. This also means that the cookie that it sets is not going to be used? Django basically allows you to authenticate once and then store the fact in the session data, correct? So Django's session cokie, rather than the login system cookie is going to be used from there on.
pq
Yes. You may want to store your API site's cookie in your profile object so you can re-use it until it expires, and/or perhaps find a way to proxy to that site for the update_profile etc. Without knowing more details of your situation that is how I would approach it.
dar
+2  A: 

The proper approach to substitute authentication from django's out-of-the-box to your own is to substitute your classes in the AUTHENTICATION_BACKENDS tuple in settings.py as described in http://docs.djangoproject.com/en/dev/topics/auth/#specifying-authentication-backends. This is incredibly useful for just the issue you're describing.

A good example of an authentication backend done this way is django-cas. This uses CAS to authenticate in a django application. You can use this as your template and just write hooks into your own authentication system identically.

HTH

Jose Boveda
Thanks for the example. I'm looking into it...
pq
That example was very useful, but it's specific to CAS. The authentication is against some ticket. After I come back from the login url of my external login system, I'll have a cookie. That's all I can authenticate against.
pq
Oh, wait, I think I figured it out. Your example has an extra redirect, b/n the external login url and next, within which cookies can be examined. Nice. Let me try that.
pq
This all worked fine. But... If a user is coming from another site and is already authenticated (means we have a domain cookie) django still doesn't know this. Is there a hook in creating a session to handle this?
pq