[Django] #33231: def authenticate doesn't raise ImproperlyConfigured for incorrect AUTHENTICATION_BACKENDS (with custom backends)

8 views
Skip to first unread message

Django

unread,
Oct 28, 2021, 8:06:54 AM10/28/21
to django-...@googlegroups.com
#33231: def authenticate doesn't raise ImproperlyConfigured for incorrect
AUTHENTICATION_BACKENDS (with custom backends)
-------------------------------------+-------------------------------------
Reporter: JunKi | Owner: JunKi Yoon
Yoon |
Type: New | Status: assigned
feature |
Component: | Version: 3.2
contrib.auth | Keywords: authenticate,
Severity: Normal | AUTHENTICATION_BACKENDS
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
def authenticate doesn't raise ImproperlyConfigured for incorrect
AUTHENTICATION_BACKENDS (with custom backends)

In my opinion, if an TypeError occurs, there is a problem with
AUTHENTICATION_BACKENDS configure,
so raise ImproperlyConfigured should be performed.

Let's say you have a custom authentication backend like this:

{{{
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend',
'myapp.backends.CustomAuth']
}}}

{{{
# myapp.backends.py
class CustomAuth(BaseBackend):
def authenticate(self, username=None, password=None):
# blahblah..
}}}

In this case, if request is not included as a parameter in the def
authenticate function of the CustomAuth class, a TypeError occurs.

Both ModelBackend and CustomAuth fail authentication, and you can't even
guess that the settings(custom backend) are wrong. So I think raise
ImproperlyConfigured is necessary.


{{{

@sensitive_variables('credentials')
def authenticate(request=None, **credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend, backend_path in _get_backends(return_tuples=True):
backend_signature = inspect.signature(backend.authenticate)
try:
backend_signature.bind(request, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments.
Try the next one.
continue
try:
user = backend.authenticate(request, **credentials)
except PermissionDenied:
# This backend says to stop in our tracks - this user should
not be allowed in at all.
break
if user is None:
continue
# Annotate the user object with the path of the backend.
user.backend = backend_path
return user

# The credentials supplied are invalid to all backends, fire signal
user_login_failed.send(sender=__name__,
credentials=_clean_credentials(credentials), request=request)
}}}

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

Django

unread,
Nov 1, 2021, 7:30:17 AM11/1/21
to django-...@googlegroups.com
#33231: authenticate() doesn't raise ImproperlyConfigured for incorrect
authentication backends.
-------------------------------------+-------------------------------------
Reporter: JunKi Yoon | Owner: JunKi
| Yoon
Type: New feature | Status: closed
Component: contrib.auth | Version: 3.2
Severity: Normal | Resolution: wontfix
Keywords: authenticate, | Triage Stage:
AUTHENTICATION_BACKENDS | Unreviewed
Has patch: 0 | Needs documentation: 0

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

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


Comment:

Django supports authentication backends with different set of credentials,
so they can have `authenticate()` methods with different signatures. For
example:
- `authenticate(self, request, token=None)` and
- `authenticate(self, request, username=None, password=None)`

once you can call it with a `token` and once with an
`username`/`password`. Both calls are valid. That's why `TypeError` must
be ignored (see also #31968).

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

Django

unread,
Nov 1, 2021, 9:22:36 PM11/1/21
to django-...@googlegroups.com
#33231: authenticate() doesn't raise ImproperlyConfigured for incorrect
authentication backends.
-------------------------------------+-------------------------------------
Reporter: JunKi Yoon | Owner: JunKi
| Yoon
Type: New feature | Status: closed
Component: contrib.auth | Version: 3.2
Severity: Normal | Resolution: wontfix
Keywords: authenticate, | Triage Stage:
AUTHENTICATION_BACKENDS | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by JunKi Yoon):

Replying to [comment:1 Mariusz Felisiak]:


> Django supports authentication backends with different set of
credentials, so they can have `authenticate()` methods with different
signatures. For example:
> - `authenticate(self, request, token=None)` and
> - `authenticate(self, request, username=None, password=None)`
>
> once you can call it with a `token` and once with an
`username`/`password`. Both calls are valid. That's why `TypeError` must
be ignored (see also #31968).

> Thanks for the detailed reply. I completely understand.
Have a good day:)

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

Reply all
Reply to author
Forward
0 new messages