Avoid deleting users when executing searches or when querying users by id
#28,255 创建于 2024年3月27日
仓库指标
- Star
- (34,398 star)
- PR 合并指标
- (平均合并 6天 19小时) (30 天内合并 384 个 PR)
描述
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
ldap
Describe the bug
In a realm where there is an additional user provider registered and transactions from this provider are enlisted after completion, it might happen that a user is created in the local storage but not necessarily on the additional user provider.
Taking the LDAP provider as an example, a user is created to the local storage but it fails to create the user in LDAP when there are failures executing the LDAP transaction enlisted after completion. This happens because JPA and LDAP transactions are isolated (no 2-phase commit protocol) and JPA transactions are committed first.
As a result, the user is persisted to the local storage and set with a federation link pointing to the LDAP provider.
However, there is an unusual mechanism to work around this problem that removes the user from the local storage whenever there is a user lookup based on its id. See https://github.com/keycloak/keycloak/blob/main/model/storage-private/src/main/java/org/keycloak/storage/UserStorageManager.java#L369.
That means that Keycloak can eventually execute delete statements in the database when searching users, something not really expected when running searches or querying users by id.
This issue is about reviewing this mechanism and avoiding removing users when querying them. Instead, we should come up with a solution based on the default transaction handling mechanism to remove the user when failing to create a user due to errors in any transaction enlister after completion.
Version
24.0.2
Regression
- The issue is a regression
Expected behavior
- Do not remove users during searches or during lookups by id when they don't exist in a user provider other than the local storage
- Leverage the default transaction handling mechanism to properly remove users from the local storage when they can't be created due to failures in transactions enlisted after completion
Actual behavior
- Users are removed during searches or during lookups by id because they are not created in a user provider other than the local storage
- Not using the default transaction handling mechanism to recover from failures when executing transactions enlisted after completion
How to Reproduce?
Run org.keycloak.testsuite.federation.ldap.LDAPProvidersIntegrationTest#testSyncRegistrationEmailRDNNoDefault and query the database after failing to create newuser1.
Anything else?
No response