Should django.contrib.auth.authenticate check is_active?

174 views
Skip to first unread message

Daniel Tao

unread,
Apr 11, 2019, 1:43:20 PM4/11/19
to Django developers (Contributions to Django itself)
This is essentially an RFC. I've become more familiar with Django's authentication backend system lately, and something has stood out to me that I'd like to draw attention to.

A new site built with Django is likely to use the default ModelBackend, which includes a user_can_authenticate method that returns False for inactive users (where is_active = False). This can create the expectation that inactive users should not be able to authenticate as a general rule.

The development team might later choose to introduce some custom authentication backends, for example to authenticate with an external service or using API tokens, without realizing that these also need to check the user's is_active field in order to preserve existing behavior (which may have become enshrined in the team's policies, for example if they had been setting is_active = False on accounts that had been detected performing malicious activity).

In my opinion it would be desirable in a large percentage of cases to move the logic in user_can_authenticate out of ModelBackend specifically and into the authenticate method itself, so that inactive users are blocked from authenticating using any backend. This would remove the burden from developers of authentication backends to remember to check for is_active in each one.

An obvious problem with changing the default behavior is that it would not be backwards compatible. How each application interprets is_active is up to that application, and some may have authentication backends that allow inactive users to authenticate by design. One option for to addressing that would be to introduce a setting such as AUTHENTICATION_REQUIRE_ACTIVE, set to False by default (but perhaps explicitly set to True for new Django projects created with the startproject command), which could be enabled for a given application to apply this requirements consistently in a future-proof way.

Dan Davis

unread,
Apr 11, 2019, 10:57:02 PM4/11/19
to Django developers (Contributions to Django itself)
So, federated login systems such as often handle only user identity authentication, which is what the AuthBackend does. Sometimes, users can self-register, and systems such as django-cas-ng (for CAS, not Oauth2).   Oauth2, although actually granting authorization to the identity provider's platform (e.g. to a Google user's profile, or even their email/calendar APIs), are often still used just for the purpose of identity verification.

You are correct that is_active can become a thing that developers must think about in designing a system, but because it has to do with authorization to login and use the Django project/site, I think it is still a concern of authentication.   Also, while the is_active field is part of the standard user model, it is a 1-line change to disable this check:

Many authentication backends subclass the ModelBackend, but they don't have to do so and can easily override the user_can_authenticate() method.

Does this answer your question?

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/19cbe676-ab7a-4dc9-98ea-d2cfe767695b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages