Fixed #25232 -- Made ModelBackend/RemoteUserBackend reject inactive users.

This commit is contained in:
Alexander Gaevsky 2016-02-05 16:46:19 +02:00 committed by Tim Graham
parent 1555d50ea4
commit e0a3d93730
11 changed files with 216 additions and 30 deletions

View file

@ -64,9 +64,20 @@ remote users. These interfaces work with users stored in the database
regardless of ``AUTHENTICATION_BACKENDS``.
.. note::
Since the ``RemoteUserBackend`` inherits from ``ModelBackend``, you will
still have all of the same permissions checking that is implemented in
``ModelBackend``.
Since the ``RemoteUserBackend`` inherits from ``ModelBackend``, you will
still have all of the same permissions checking that is implemented in
``ModelBackend``.
Users with :attr:`is_active=False
<django.contrib.auth.models.User.is_active>` won't be allowed to
authenticate. Use
:class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend` if
you want to allow them to.
.. versionchanged:: 1.10
In older versions, inactive users weren't rejected as described above.
If your authentication mechanism uses a custom HTTP header and not
``REMOTE_USER``, you can subclass ``RemoteUserMiddleware`` and set the

View file

@ -76,15 +76,26 @@ Fields
This doesn't necessarily control whether or not the user can log in.
Authentication backends aren't required to check for the ``is_active``
flag, and the default backends do not. If you want to reject a login
based on ``is_active`` being ``False``, it's up to you to check that in
your own login view or a custom authentication backend. However, the
flag but the default backend
(:class:`~django.contrib.auth.backends.ModelBackend`) and the
:class:`~django.contrib.auth.backends.RemoteUserBackend` do. You can
use :class:`~django.contrib.auth.backends.AllowAllUsersModelBackend`
or :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend`
if you want to allow inactive users to login. In this case, you'll also
want to customize the
:class:`~django.contrib.auth.forms.AuthenticationForm` used by the
:func:`~django.contrib.auth.views.login` view (which is the default)
*does* perform this check, as do the permission-checking methods such
as :meth:`~django.contrib.auth.models.User.has_perm` and the
authentication in the Django admin. All of those functions/methods will
return ``False`` for inactive users.
:func:`~django.contrib.auth.views.login` view as it rejects inactive
users. Be aware that the permission-checking methods such as
:meth:`~django.contrib.auth.models.User.has_perm` and the
authentication in the Django admin all return ``False`` for inactive
users.
.. versionchanged:: 1.10
In older versions,
:class:`~django.contrib.auth.backends.ModelBackend` and
:class:`~django.contrib.auth.backends.RemoteUserBackend` allowed
inactive users to authenticate.
.. attribute:: is_superuser
@ -488,6 +499,32 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
Returns whether the ``user_obj`` has any permissions on the app
``app_label``.
.. method:: ModelBackend.user_can_authenticate()
.. versionadded:: 1.10
Returns whether the user is allowed to authenticate. To match the
behavior of :class:`~django.contrib.auth.forms.AuthenticationForm`
which :meth:`prohibits inactive users from logging in
<django.contrib.auth.forms.AuthenticationForm.confirm_login_allowed>`,
this method returns ``False`` for users with :attr:`is_active=False
<django.contrib.auth.models.User.is_active>`. Custom user models that
don't have an :attr:`~django.contrib.auth.models.CustomUser.is_active`
field are allowed.
.. class:: AllowAllUsersModelBackend
.. versionadded:: 1.10
Same as :class:`ModelBackend` except that it doesn't reject inactive users
because :meth:`~ModelBackend.user_can_authenticate` always returns ``True``.
When using this backend, you'll likely want to customize the
:class:`~django.contrib.auth.forms.AuthenticationForm` used by the
:func:`~django.contrib.auth.views.login` view by overriding the
:meth:`~django.contrib.auth.forms.AuthenticationForm.confirm_login_allowed`
method as it rejects inactive users.
.. class:: RemoteUserBackend
Use this backend to take advantage of external-to-Django-handled
@ -529,3 +566,21 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
new user is created, and can be used to perform custom setup actions, such
as setting the user's groups based on attributes in an LDAP directory.
Returns the user object.
.. method:: RemoteUserBackend.user_can_authenticate()
.. versionadded:: 1.10
Returns whether the user is allowed to authenticate. This method returns
``False`` for users with :attr:`is_active=False
<django.contrib.auth.models.User.is_active>`. Custom user models that don't
have an :attr:`~django.contrib.auth.models.CustomUser.is_active` field are
allowed.
.. class:: AllowAllUsersRemoteUserBackend
.. versionadded:: 1.10
Same as :class:`RemoteUserBackend` except that it doesn't reject inactive
users because :attr:`~RemoteUserBackend.user_can_authenticate` always
returns ``True``.

View file

@ -669,6 +669,15 @@ Miscellaneous
calling ``Command.execute()``, pass the command object as the first argument
to ``call_command()``.
* :class:`~django.contrib.auth.backends.ModelBackend` and
:class:`~django.contrib.auth.backends.RemoteUserBackend` now reject inactive
users. This means that inactive users can't login and will be logged
out if they are switched from ``is_active=True`` to ``False``. If you need
the previous behavior, use the new
:class:`~django.contrib.auth.backends.AllowAllUsersModelBackend` or
:class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend`
in :setting:`AUTHENTICATION_BACKENDS` instead.
.. _deprecated-features-1.10:
Features deprecated in 1.10

View file

@ -235,10 +235,17 @@ for example, to control anonymous access.
Authorization for inactive users
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An inactive user is a one that is authenticated but has its attribute
``is_active`` set to ``False``. However this does not mean they are not
authorized to do anything. For example they are allowed to activate their
account.
An inactive user is a one that has its
:attr:`~django.contrib.auth.models.User.is_active` field set to ``False``. The
:class:`~django.contrib.auth.backends.ModelBackend` and
:class:`~django.contrib.auth.backends.RemoteUserBackend` authentication
backends prohibits these users from authenticating. If a custom user model
doesn't have an :attr:`~django.contrib.auth.models.CustomUser.is_active` field,
all users will be allowed to authenticate.
You can use :class:`~django.contrib.auth.backends.AllowAllUsersModelBackend`
or :class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend` if you
want to allow inactive users to authenticate.
The support for anonymous users in the permission system allows for a scenario
where anonymous users have permissions to do something while inactive
@ -247,6 +254,10 @@ authenticated users do not.
Do not forget to test for the ``is_active`` attribute of the user in your own
backend permission methods.
.. versionchanged:: 1.10
In older versions, the :class:`~django.contrib.auth.backends.ModelBackend`
allowed inactive users to authenticate.
Handling object permissions
~~~~~~~~~~~~~~~~~~~~~~~~~~~