Ensure searched LDAPObject is properly cached before other methods that trigger user validation run

Closes #34050

Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
This commit is contained in:
Stefan Guilhen 2024-10-28 14:48:49 -03:00 committed by Pedro Igor
parent bf3162ff38
commit 4690e00d91
2 changed files with 18 additions and 15 deletions

View file

@ -621,18 +621,19 @@ public class LDAPStorageProvider implements UserStorageProvider,
* @return ldapUser corresponding to local user or null if user is no longer in LDAP * @return ldapUser corresponding to local user or null if user is no longer in LDAP
*/ */
protected LDAPObject loadAndValidateUser(RealmModel realm, UserModel local) { protected LDAPObject loadAndValidateUser(RealmModel realm, UserModel local) {
LDAPObject existing = userManager.getManagedLDAPUser(local.getId()); // getFirstAttribute triggers validation and another call to this method, so we run it before checking the cache
String uuidLdapAttribute = local.getFirstAttribute(LDAPConstants.LDAP_ID);
LDAPObject existing = userManager.getManagedLDAPObject(local.getId());
if (existing != null) { if (existing != null) {
return existing; return existing;
} }
String uuidLdapAttribute = local.getFirstAttribute(LDAPConstants.LDAP_ID);
LDAPObject ldapUser = loadLDAPUserByUuid(realm, uuidLdapAttribute); LDAPObject ldapUser = loadLDAPUserByUuid(realm, uuidLdapAttribute);
if(ldapUser == null){ if(ldapUser == null){
return null; return null;
} }
userManager.setManagedLDAPObject(local.getId(), ldapUser);
LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig()); LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig());
if (ldapUser.getUuid().equals(local.getFirstAttribute(LDAPConstants.LDAP_ID))) { if (ldapUser.getUuid().equals(local.getFirstAttribute(LDAPConstants.LDAP_ID))) {

View file

@ -31,6 +31,7 @@ import org.keycloak.storage.ldap.mappers.LDAPTransaction;
*/ */
public class LDAPStorageUserManager { public class LDAPStorageUserManager {
private final Map<String, LDAPObject> managedLDAPObjects = new HashMap<>();
private final Map<String, ManagedUserEntry> managedUsers = new HashMap<>(); private final Map<String, ManagedUserEntry> managedUsers = new HashMap<>();
private final LDAPStorageProvider provider; private final LDAPStorageProvider provider;
@ -43,9 +44,16 @@ public class LDAPStorageUserManager {
return entry==null ? null : entry.getManagedProxiedUser(); return entry==null ? null : entry.getManagedProxiedUser();
} }
public LDAPObject getManagedLDAPUser(String userId) { public LDAPObject getManagedLDAPObject(String userId) {
ManagedUserEntry entry = managedUsers.get(userId); return managedLDAPObjects.get(userId);
return entry==null ? null : entry.getLdapUser(); }
public void setManagedLDAPObject(String userId, LDAPObject ldapObject) {
LDAPObject object = managedLDAPObjects.get(userId);
if (object != null) {
throw new IllegalStateException("Don't expect to have ldap object for user " + userId);
}
managedLDAPObjects.put(userId, ldapObject);
} }
public LDAPTransaction getTransaction(String userId) { public LDAPTransaction getTransaction(String userId) {
@ -66,7 +74,7 @@ public class LDAPStorageUserManager {
} }
LDAPTransaction ldapTransaction = new LDAPTransaction(provider, ldapObject); LDAPTransaction ldapTransaction = new LDAPTransaction(provider, ldapObject);
ManagedUserEntry newEntry = new ManagedUserEntry(proxiedUser, ldapObject, ldapTransaction); ManagedUserEntry newEntry = new ManagedUserEntry(proxiedUser, ldapTransaction);
managedUsers.put(userId, newEntry); managedUsers.put(userId, newEntry);
} }
@ -79,12 +87,10 @@ public class LDAPStorageUserManager {
private static class ManagedUserEntry { private static class ManagedUserEntry {
private final UserModel managedProxiedUser; private final UserModel managedProxiedUser;
private final LDAPObject ldapUser;
private final LDAPTransaction ldapTransaction; private final LDAPTransaction ldapTransaction;
public ManagedUserEntry(UserModel managedProxiedUser, LDAPObject ldapUser, LDAPTransaction ldapTransaction) { public ManagedUserEntry(UserModel managedProxiedUser, LDAPTransaction ldapTransaction) {
this.managedProxiedUser = managedProxiedUser; this.managedProxiedUser = managedProxiedUser;
this.ldapUser = ldapUser;
this.ldapTransaction = ldapTransaction; this.ldapTransaction = ldapTransaction;
} }
@ -92,10 +98,6 @@ public class LDAPStorageUserManager {
return managedProxiedUser; return managedProxiedUser;
} }
public LDAPObject getLdapUser() {
return ldapUser;
}
public LDAPTransaction getLdapTransaction() { public LDAPTransaction getLdapTransaction() {
return ldapTransaction; return ldapTransaction;
} }