Few clarifications about the authentication system

Good day,

I am currently studying Django’s authentication system and I have few blockers.

No. 1:

Once a user has authenticated, Django stores which backend was used to authenticate the user in the user’s session, and reuses the same backend for the duration of that session whenever access to the currently authenticated user is needed.

When a user logs in, the user’s ID and the backend that was used for authentication are saved in the user’s session. This allows the same authentication backend to fetch the user’s details on a future request.

Does that mean either django.contrib.auth.authenticate and django.contrib.auth.login saves the auth backend that was used in the user’s session?

Also, when does the auth backend get reused? Isn’t a session ID saved in the database when the user logs in so that we don’t have to authenticate every time?

No. 2:

The permissions given to the user will be the superset of all permissions returned by all backends. That is, Django grants a permission to a user that any one backend grants.

Does that mean an authenticated user has all the possible permissions set in each backend? When BackendA matches the user but BackendB sets PermissionA, will the user have the PermissionA? If yes, I thought processing backends during authentication stops when a user is authenticated or PermissionDenied is returned?

Also, how is permission checked? Does Django go straight to the auth backends?

And, when are permissions cached? Is it for the very first time we check for a permission of a user and it caches all the possible permissions? If no, then why do we have to refetch the user if we add a new permission to it?

Thank you so much in advance.

The authenticate function attaches the backend as an attribute of the user object. The login function saves the backend as a key in the session.

Every time a request is made and the User object is not cached.

The user isn’t reauthenticated - it’s not like the credentials are reused. But the backend defines where the information about the user is stored.

You need to read that in the context of the entire section. It starts out with:

Custom auth backends can provide their own permissions.

[emphasis added]

It says “can”, not “will”, or “must”. There is no requirement or even necessarily an expectation that an authorization backend will provide a set of permission lookup overrides.

The BaseBackend as a superclass returns nothing. The ModelBackend returns what’s defined on the model. Other backends may do something different.

That is correct - for authentication. Authorization (permissions) is a separate function. But yes, a “PermissionsDenied” does short-circuit the process to prevent further tests.

Permissions are checked by views. Each view is responsible for ensuring the requested user has the necessary permissions.

That would depend upon the individual backend. There’s no requirement (or prohibition) on cacheing permissions.

Because you can’t rely upon them not being cached.

If you have further questions, I suggest you spend some time reading the source code for the various modules involved. The backends and the user methods are all very straight forward.

1 Like

Thank you so much! That cleared my confusions. Will check their source code.