multiple authentication and session keys

1 view
Skip to first unread message

Gary Wilson

unread,
Aug 4, 2006, 1:42:39 AM8/4/06
to Django developers
So, the mutli authentication seems to work well for the use case of a
site accepting more than one authentication source to access some area,
but not so well for the use case of a site accepting one source of
authentication in one area and another source of authentication in a
different area.

The contrib.auth.login function currently writes the user's id to
session['_auth_user_id'] and the backend to
session['_auth_user_backend']. When using more than one authentication
backend, the session data gets stomped on. I propose that the session
data be keyed by backend somehow so that authentication session data is
kept separate.

The login function would change to key the session data by backend.
The logout function would log the user out of all backends, or
optionally take in a backend to log the user out of only that
particular backend. The get_user function with no parameters would
return the first user object it finds calling backend.get_user() for
each backend in AUTHENTICATION_BACKENDS in order, or optionally take a
backend to try and get the user from.

Scott Paul Robertson

unread,
Aug 12, 2006, 6:32:58 PM8/12/06
to django-d...@googlegroups.com

You also run into a problem if you change the authentication backends
and don't clear out your cookie. Django will fail trying to authenticate
with a now non-existent backend. I can grab the traceback if it's
needed.

--
Scott Paul Robertson
http://spr.mahonri5.net
GnuPG FingerPrint: 09ab 64b5 edc0 903e 93ce edb9 3bcc f8fb dc5d 7601

Gary Wilson

unread,
Aug 30, 2006, 12:49:07 AM8/30/06
to Django developers
So I hit another little snag today related to this. The
contrib.auth.middleware.LazyUser calls contrib.auth.get_user (knowing
where to get the user from based on the backend stored in
session['_auth_user_backend']), which will return an
authentication-backend-dependent user object. This user object
shouldn't have to conform to contrib.auth.models.User's interface, yet
core.context_processors.auth calls
request.user.get_and_delete_messages(). This means that whatever user
object I return with my backend must implement a
get_and_delete_messages method.

Another problem with the request.user.get_and_delete_messages() call is
that request.user is a LazyUser. So LazyUser is doing us no good since
this call will always put LazyUser to work.

Adrian Holovaty

unread,
Aug 30, 2006, 1:31:25 PM8/30/06
to django-d...@googlegroups.com

Thanks for bringing this up, Gary. The get_and_delete_messages() thing
has always bothered me -- if it's activated, we do it for every
request. I suppose we could make the 'messages' part of the context
processor lazy, so that it would only call get_and_delete_messages()
if that variable were accessed in the template... Thoughts?

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com

Cheng Zhang

unread,
Aug 31, 2006, 1:25:03 AM8/31/06
to django-d...@googlegroups.com

On Aug 31, 2006, at 1:31 AM, Adrian Holovaty wrote:

> Thanks for bringing this up, Gary. The get_and_delete_messages() thing
> has always bothered me -- if it's activated, we do it for every
> request. I suppose we could make the 'messages' part of the context
> processor lazy, so that it would only call get_and_delete_messages()
> if that variable were accessed in the template... Thoughts?

+1.
In addition, we can save a few SQL queries every request.


-Cheng Zhang
http://www.ifaxian.com
1st Django powered site in Chinese ;-)


Gary Wilson

unread,
Aug 31, 2006, 11:36:44 PM8/31/06
to Django developers
Adrian Holovaty wrote:
> Thanks for bringing this up, Gary. The get_and_delete_messages() thing
> has always bothered me -- if it's activated, we do it for every
> request. I suppose we could make the 'messages' part of the context
> processor lazy, so that it would only call get_and_delete_messages()
> if that variable were accessed in the template... Thoughts?

We could make the messages part lazy, but we also don't want to have to
pass it request.user because that defeats the purpose of LazyUser.
What if we gave the LazyUser class a lazy "messages" property and dont
pass a "messages" context variable in the context processor. The
templates would instead access messages through the "user" context
variable. Of course, this would make the templates backwards
incompatible. As far as Django code, the messages variable seems to
get used only in contrib/admin/templates/admin/base.html.

I think it would be a good idea to add some re-usable Lazy object class
to Django, something like this:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363602
This lazy loading stuff is a common scenario.

Reply all
Reply to author
Forward
0 new messages