[Django] #23925: django.contrib.auth.authenticate sets the wrong backend path

10 views
Skip to first unread message

Django

unread,
Nov 27, 2014, 4:04:03 AM11/27/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+--------------------
Reporter: sdeprez | Owner: nobody
Type: Bug | Status: new
Component: contrib.auth | Version: 1.7
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Easy pickings: 0 | UI/UX: 0
------------------------------+--------------------
The `django.contrib.auth.authenticate` function currently tries to
authenticate a user by checking each backend in
`settings.AUTHENTICATION_BACKENDS`, and when it has found one that works,
it annotates the user by adding a `path` attribute that is the path of the
backend (as a Python object). However the path is computed based on the
`__class__` attribute of the backend object, which give the "real" path of
the object, and NOT based on the path given by
`settings.AUTHENTICATION_BACKENDS`.

This is problematic beacause they may differ, and thus the later check `if
backend_path in settings.AUTHENTICATION_BACKENDS` in
`django.contrib.auth.get_user` can fail whereas it should not.

Steps to reproduce the bug :
- create a custom backend in some module :
`my_app.my_module_backend.CustomBackend`

- create another module that imports this module. For instance, it's
common practice to import it in the `__init__.py` file of the package. So,
in `my_app/__init__.py` put `from my_app import CustomBackend`.

- Set `AUTHENTICATION_BACKENDS = my_app.CustomBackend`

- Run django, create an user and try to login. Everything will go fine (no
errors), except that you WON'T be logged, because of
`django.contrib.auth.get_user` that will return an AnonymousUser. This can
be very painful to track and this can even lead to infinite loops if your
`LOGIN_REDIRECT_URL` is an url that requires login, because the session
key will be set but an `AnonymousUser` is returned.

I attached a patch that fixes that, by setting the actual path used in
`AUTHENTICATION_BACKENDS` in the user, without any changes to the working
public API.

--
Ticket URL: <https://code.djangoproject.com/ticket/23925>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 27, 2014, 4:50:21 AM11/27/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+--------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------------+--------------------------------------
Changes (by sdeprez):

* status: new => assigned
* cc: sdeprez (added)
* needs_better_patch: => 0
* needs_tests: => 0
* owner: nobody => sdeprez
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:1>

Django

unread,
Nov 27, 2014, 4:53:26 AM11/27/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+--------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+--------------------------------------
Changes (by sdeprez):

* has_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:2>

Django

unread,
Nov 27, 2014, 4:54:38 AM11/27/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+--------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+--------------------------------------
Description changed by sdeprez:

Old description:

New description:

The `django.contrib.auth.authenticate` function currently tries to
authenticate a user by checking each backend in
`settings.AUTHENTICATION_BACKENDS`, and when it has found one that works,
it annotates the user by adding a `path` attribute that is the path of the
backend (as a Python object). However the path is computed based on the
`__class__` attribute of the backend object, which give the "real" path of
the object, and NOT based on the path given by
`settings.AUTHENTICATION_BACKENDS`.

This is problematic beacause they may differ, and thus the later check `if
backend_path in settings.AUTHENTICATION_BACKENDS` in
`django.contrib.auth.get_user` can fail whereas it should not.

Steps to reproduce the bug :
- create a custom backend in some module :
`my_app.my_module_backend.CustomBackend`

- create another module that imports this module. For instance, it's
common practice to import it in the `__init__.py` file of the package. So,
in `my_app/__init__.py` put `from my_app import CustomBackend`.

- Set `AUTHENTICATION_BACKENDS = my_app.CustomBackend`

- Run django, create an user and try to login. Everything will go fine (no
errors), except that you WON'T be logged, because of
`django.contrib.auth.get_user` that will return an AnonymousUser. This can
be very painful to track and this can even lead to infinite loops if your
`LOGIN_REDIRECT_URL` is an url that requires login, because the session
key will be set but an `AnonymousUser` is returned.

A pull request is linked which addresses the issue by setting the actual


path used in `AUTHENTICATION_BACKENDS` in the user, without any changes to

the working public API. All the tests passed under SQLite.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:3>

Django

unread,
Nov 27, 2014, 8:24:52 AM11/27/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+------------------------------------

Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+------------------------------------
Changes (by timgraham):

* has_patch: 0 => 1
* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:4>

Django

unread,
Nov 28, 2014, 7:15:44 AM11/28/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


Comment:

Comments for improvement are on the PR, please uncheck "Patch needs
improvement" when you update it.

--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:5>

Django

unread,
Nov 28, 2014, 10:02:22 AM11/28/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: assigned
Component: contrib.auth | Version: 1.7

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
------------------------------+------------------------------------
Changes (by sdeprez):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:6>

Django

unread,
Nov 28, 2014, 10:48:00 AM11/28/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: closed
Component: contrib.auth | Version: 1.7
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"9e80c5f457340126adcae375d6de5ee64d6075b9"]:
{{{
#!CommitTicketReference repository=""
revision="9e80c5f457340126adcae375d6de5ee64d6075b9"
Fixed #23925 -- Allowed settings.AUTHENTICATION_BACKENDS to reference
import aliases
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:7>

Django

unread,
Dec 15, 2014, 10:13:27 AM12/15/14
to django-...@googlegroups.com
#23925: django.contrib.auth.authenticate sets the wrong backend path
------------------------------+------------------------------------
Reporter: sdeprez | Owner: sdeprez
Type: Bug | Status: closed
Component: contrib.auth | Version: 1.7

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"0d5ca7b560dbb827eea625e53e4a6a67c29d7964"]:
{{{
#!CommitTicketReference repository=""
revision="0d5ca7b560dbb827eea625e53e4a6a67c29d7964"
Moved an import in an auth test; refs #23925.

This keeps tests/__init__.py from importing other modules and may fix a
problem
with test discovery revealed in formtools tests on Travis CI.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/23925#comment:8>

Reply all
Reply to author
Forward
0 new messages