Open sumpfralle opened 6 months ago
Well, that's really up to the admin to configure. If you don't want your user to be able to change their password (because they should use the LDAP one), then they should be denied to run a password change flow (by default default-password-change
).
Just for the clarification of the use case:
This works beautifully and is in line with the intended use-case of the LDAP feature in authentik.
The only problem is, that authentik is storing a password in its own internal database, even though the configuration setting "update internal password on login" is disabled. This was probably just an oversight and should (IMO) obviously be fixed.
I've been unable to replicate the problem.
So it seems the option is working as expected.
Maybe the problem is that the previously cached password are still used, so a workaround would be to empty them
I've been unable to replicate the problem.
Thank you for trying to reproduce the problem!
Please take a look at the steps (5) and (6) of my procedure above: the problem is the password change via authentik. The changed password should just be synced to the LDAP server (this always worked), but it should not be stored locally in authentik's database.
Ok, @sumpfralle is right If the goal of the "update internal password on login" is not having the user's password hash in the local database, it's not enough.
I've replicated two situations that stores the user's password hash in the local database, even with the option "update internal password on login" NOT selected:
So, if the goal was to not have a password hash in the authetik database, these two scenarios should be considered to not store the hash locally
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
With the User password writeback
option enabled, a password will only be written to LDAP when it is written to a user in authentik. I'm not sure what the best option would be to make these two steps separate without having to make a lot of assumptions in the code.
The two involved settings of the LDAP source seem to be:
- Update internal password on login: When the user logs in to authentik using the LDAP password backend, the password is stored as a hashed value in authentik. Toggle off (default setting) if you do not want to store the hashed passwords in authentik.
- User password writeback: Enable this option if you want to write password changes that are made in authentik back to LDAP.
I have the feeling, that the name of the first setting ("Update internal password on login") is a source of confusion:
The seccond setting ("User password writeback") seems to be quite clear:
I'm not sure what the best option would be to make these two steps separate without having to make a lot of assumptions in the code.
I guess (without having looked at the details), that an improved wording of the settings would remove the need for these unsuitable assumptions.
some updated wording that I think makes it quite a bit clearer what the options mean/do
IMO this combination of options is not suitable for the goals of authentik.
As @kukoarmas wrote above (similar to my previous words):
So, if the goal was to not have a password hash in the authetik database, these two scenarios should be considered to not store the hash locally
Thus, I would recommend the following two options:
1) Cache the users' passwords in authentik
Whenever a user logs in via authentik or changes the password via authentik, the password hash is cached in authentik's database.
2) Update LDAP on password changes
Enable this option to write password changes submitted via authentik back to LDAP.
I think, the above would be the description of a reasonable implementation.
At the moment, I still have to delete all password hashs in authentik's database periodically (a cron job), since these cached values turn stale after external password changes. At the moment there is no configurable way to solve this problem of cache invalidation in authentik.
In order to avoid any misunderstandings, I want to summarize the current state of LDAP support in authentik:
Currently it is not possible to run authentik in combination with an LDAP service, while allowing password changes via authentik and LDAP. Trivial cause: it is currently not possible to disable authentik's password caching.
Thus, currently it is necessary to manually discard the password hashs from the authentik database (e.g. via a cron job), if password changes via LDAP (without authentik) are possible.
IMO authentik's currently available configuration settings are not consistent and should be changed. See my proposal above.
What do you refer to when saying "authentik password caching"?
What do you refer to when saying "authentik password caching"?
I refer to the fact, that authentik stores a password hash in its own database. This password hash is used for subsequent authentication requests (instead of asking the LDAP backend).
This password hash can be stored in two situations:
The unconditional storage of password hashes during a password change currently forces administrators to manually discard the password hashes from the authentik database (e.g. via cron jobs). Otherwise the authentik database may contain outdated password hashs (i.e. "user can log in with an old password").
Alright let's clarify what all of this is.
First, authentik doesn't "cache" any password. Either it writes it to its database, or not.
Now, when you have an LDAP source configured, you effectively have to deal with two password databases: the one from authentik and the one from LDAP. Interaction with those happens one two separate occasions: when the user logs in and when the user changes their password.
When a user logs in to authentik, they go through a password stage. In that password stage, you can configure which backends are to be used. This is where you can choose what combination of "standard password" (the one stored in the authentik password database), "app password" (from app tokens a user can create for out of band access to authentik), "LDAP password" (the one stored in the LDAP password database), or more recently "Kerberos password" (let's ignore that for now as this is for Kerberos sources, and works in the same way that LDAP does).
If you want users to never use the internal authentik database, then "standard password" should be deselected.
Now when the user logs in with their LDAP password, i.e. when authentik checks the user's password against LDAP (this happens here if you want to read the code), authentik allows the password to be written back to authentik if the "Update internal password on login" toggle is on (https://github.com/goauthentik/authentik/blob/main/authentik/sources/ldap/auth.py#L43). The use case here is that if LDAP goes down, users will still be able to log in using the password stored in authentik (the password is "cached" but not really).
Whether that's a good idea or not is really not up to us. It depends on the specific setup where authentik is used, and in many cases is a valid setup. In any case, as it's configurable behaviour, it's up to the admin to configure to their needs.
Nothing much to say here, as that happens outside authentik. When the user next logs in to authentik, provided the password stage is configured to use the LDAP backend, the new password will be used as described above.
Password changes happen through a "Stage configuration" flow, configured on the password stage itself as "Configuration flow" (if you have many password stages, the first one is picked and shown in the user settings).
If no configuration flow is configured, the user will not be able to change their password from authentik.
If a configuration flow is configured, the user will go through it, and all validation policies on the prompt stages there will be run. If the "User password writeback" option is turned on in the LDAP source, the password will also be validated against the LDAP directory, if that directory is an Active Directory (https://github.com/goauthentik/authentik/blob/main/authentik/sources/ldap/signals.py#L42, https://github.com/goauthentik/authentik/blob/main/authentik/sources/ldap/password.py#L71, https://github.com/goauthentik/authentik/blob/main/authentik/sources/ldap/password.py#L138).
Then, the password will always be written to authentik's database.
Then, if the "User password writeback" option is turned on in the LDAP source, the password will be written back to LDAP (which happens here).
Now to answer the initial issue, if you want users to be able to change their password from authentik, and that password should be written back to LDAP, but only the password from LDAP should be used for log in, you should configure the following:
In the LDAP source:
In the Password stage:
Describe the bug With the new option "update internal password on login" (
password_login_update_internal_password
) disabled, I expected, that passwords are not written to the database anymore. But the password is still written to the internal database, if a user changes his password via authentik.To Reproduce Steps to reproduce the behavior:
password
field in theauthentik_core_user
table for this user is still emptypw1
)password
field of theauthentik_core_user
table is non-empty (probably containing the hash ofpw1
)pw2
pw1
: works (probably based on thepassword
field stored in authentik's database)pw2
: works (probably based on the password stored in LDAP)Expected behavior I expected, that the new setting "update internal password on login" is supposed to fix issue #6122 (it was closed by #8377). In this case, the password field should never be written.
Thus, the following details seem to be undesirable from my point of view:
password
field in theauthentik_core_user
table should stay empty under all circumstances.pw1
) should not be usable anymore after a password change in LDAP.Version and Deployment (please complete the following information):