Keycloak 15.0.2 Auto Delete User

1,441 views
Skip to first unread message

Hua Yao

unread,
Nov 10, 2021, 12:23:14 AM11/10/21
to Keycloak Dev
Hi team, 

Keycloak seems automatically delete users from Keycloak randomly... 

It happens quite often. anyone knows if this is a known bug or my config is wrong? 

log as below: 



2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.SQL] (ForkJoinPool.commonPool-worker-117) 
    delete 
    from
        USER_ATTRIBUTE 
    where
        ID=?
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.SQL] (ForkJoinPool.commonPool-worker-117) 
    delete 
    from
        USER_ATTRIBUTE 
    where
        ID=?
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.SQL] (ForkJoinPool.commonPool-worker-117) 
    delete 
    from
        USER_ATTRIBUTE 
    where
        ID=?
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.SQL] (ForkJoinPool.commonPool-worker-117) 
    delete 
    from
        USER_ATTRIBUTE 
    where
        ID=?
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,848 DEBUG [org.hibernate.SQL] (ForkJoinPool.commonPool-worker-117) 
    delete 
    from
        USER_ENTITY 
    where
        ID=?
2021-11-10 10:41:56,849 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,849 DEBUG [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (ForkJoinPool.commonPool-worker-117) Skipping aggressive release due to manual disabling
2021-11-10 10:41:56,849 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (ForkJoinPool.commonPool-worker-117) Initiating JDBC connection release from afterStatement
2021-11-10 10:41:56,849 DEBUG [org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl] (ForkJoinPool.commonPool-worker-117) Initiating JDBC connection release from afterStatement
2021-11-10 10:41:56,852 DEBUG [org.hibernate.query.criteria.internal.CriteriaQueryImpl] (ForkJoinPool.commonPool-worker-117) Rendered criteria query -> select generatedAlias0.id from PermissionTicketEntity as generatedAlias0 where generatedAlias0.owner=:param0 order by generatedAlias0.id asc
2021-11-10 10:41:56,853 DEBUG [org.hibernate.hql.internal.ast.QueryTranslatorImpl] (ForkJoinPool.commonPool-worker-117) parse() - HQL: select generatedAlias0.id from org.keycloak.authorization.jpa.entities.PermissionTicketEntity as generatedAlias0 where generatedAlias0.owner=:param0 order by generatedAlias0.id asc
2021-11-10 10:41:56,853 DEBUG [org.hibernate.hql.internal.ast.ErrorTracker] (ForkJoinPool.commonPool-worker-117) throwQueryException() : no errors
2021-11-10 10:41:56,854 DEBUG [org.hibernate.hql.internal.ast.QueryTranslatorImpl] (ForkJoinPool.commonPool-worker-117) --- HQL AST ---
 \-[QUERY] Node: 'query'
    +-[SELECT_FROM] Node: 'SELECT_FROM'
    |  +-[FROM] Node: 'from'
    |  |  \-[RANGE] Node: 'RANGE'
    |  |     +-[DOT] Node: '.'
    |  |     |  +-[DOT] Node: '.'
    |  |     |  |  +-[DOT] Node: '.'
    |  |     |  |  |  +-[DOT] Node: '.'
    |  |     |  |  |  |  +-[DOT] Node: '.'
    |  |     |  |  |  |  |  +-[IDENT] Node: 'org'
    |  |     |  |  |  |  |  \-[IDENT] Node: 'keycloak'
    |  |     |  |  |  |  \-[IDENT] Node: 'authorization'
    |  |     |  |  |  \-[IDENT] Node: 'jpa'
    |  |     |  |  \-[IDENT] Node: 'entities'
    |  |     |  \-[IDENT] Node: 'PermissionTicketEntity'
    |  |     \-[ALIAS] Node: 'generatedAlias0'
    |  \-[SELECT] Node: 'select'
    |     \-[DOT] Node: '.'
    |        +-[IDENT] Node: 'generatedAlias0'
    |        \-[IDENT] Node: 'id'
    +-[WHERE] Node: 'where'
    |  \-[EQ] Node: '='
    |     +-[DOT] Node: '.'
    |     |  +-[IDENT] Node: 'generatedAlias0'
    |     |  \-[IDENT] Node: 'owner'
    |     \-[COLON] Node: ':'
    |        \-[IDENT] Node: 'param0'
    \-[ORDER] Node: 'order'
       +-[DOT] Node: '.'
       |  +-[IDENT] Node: 'generatedAlias0'
       |  \-[IDENT] Node: 'id'
       \-[ASCENDING] Node: 'asc'

Hua Yao

unread,
May 30, 2022, 12:23:54 PM5/30/22
to Keycloak Dev

Hi, 

It's quite upset that, none of the Keycloak team member reviews the reported issue. I just want to say, auto deleting a user randomly is the most serious issue of a security product. 

Stian Thorgersen

unread,
May 31, 2022, 5:01:39 AM5/31/22
to Hua Yao, Keycloak Dev
Hi,

There's nothing in Keycloak that should automatically delete users, and from what I know there are no other users that have seen this issue. 

From your bug report [1] it's hard to identify what's going on though. Are you able to track down what is causing the deletion from Keycloak's side? Is it a specific request, or a background task that is causing this? What if any changes have you done from the default distribution.


--
You received this message because you are subscribed to the Google Groups "Keycloak Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to keycloak-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/keycloak-dev/fd0c390b-3180-46a4-934b-115cc72a8651n%40googlegroups.com.

Hua Yao

unread,
May 31, 2022, 9:12:06 AM5/31/22
to stho...@redhat.com, Keycloak Dev
Hi, 

thanks a lot for your replies. Yes, I am using the default settings of keycloak (standalone mode). 

To be honest, I am not able to proof directly. But I know it has something to do with the LDAP sync function. While I turn on LDAP synchronization, I will lose one to two users accounts everyday. And keycloak will regen the user back automatically. all the user roles information get lost. 
However, if I turn off the LDAP sync option. My user list will never be changed. 

I have trying to trace the log on how the user being deleted. But it's very hard to find with the limited info. However, there is always a LDAP connection or JDBC connection exception before the delete user sql statement is executed. 

I realise this fellow encounters the same issue as me: https://github.com/keycloak/keycloak/issues/9520 


I really hope I can help to contribute to the community. we will see how. 


Thank you again for your kind replies again. 


Cheers.

Andy 
















Stian Thorgersen <stho...@redhat.com> 于2022年5月31日周二 17:01写道:

Joaquim Fellmann

unread,
Jun 1, 2022, 5:03:45 AM6/1/22
to Hua Yao, stho...@redhat.com, Keycloak Dev

Hi!

I'm 100% confident I've hit this issue as well (quite some time ago while working with LDAP user federation)
Didn't investigate more because of the automatic user re-creation. No KC specific data (OTP, roles, groups,...) was stored on the user account so deletion/re-creation wasn't really an issue.
AFAIR it had something to do with KC LDAP technical attributes getting out of sync with the LDAP user. Maybe an issue related to LDAP DN of the user being modified upstream or something like this. I'll see if I can reproduce and provide feedback if this is the case.

Regards

-- 
Joaquim


Joaquim Fellmann

unread,
Jun 1, 2022, 6:19:39 AM6/1/22
to Hua Yao, stho...@redhat.com, Keycloak Dev
This is the JIRA I reported at the time: https://issues.redhat.com/browse/KEYCLOAK-15634
Anyway this was a bug of the new Account Console that's been fixed in KC12. So I guess you've hit a different issue

-- 
Joaquim

Hua Yao

unread,
Jun 11, 2022, 5:38:30 AM6/11/22
to Keycloak Dev
Dear all, 

I managed to trace the stack of how the user is being deleted. but I get stuck at the upstream logic due to my limited Java knowledge. Here is my findings so far. 

The user is identified as 'invalid' user, and Keycloak remove it from local storage. The last msg for this user is 'Removed invalid user' from [org.keycloak.storage.UserStorageManager]

After tracing the upstream codes, I found it's called in code as below. and I highlight the executed code in YELLOW. The reason for the null return in importedUserValidation.validation failure is due to the 'LDAPObject ldapUser = loadLDAPUserByUuid(realm, uuidLdapAttribute);' returns null. 

And I am stuck here, I am not able to trace which upstream function calls this API. but I suspect some codes in LDAP sync calls either one function in below. 
Very appreciated if any of you could advise how to further trace it. 
Screenshot 2022-06-11 at 5.30.11 PM.png

/**
* Allows a UserStorageProvider to proxy and/or synchronize an imported user.
*
* @param realm
* @param user
* @return
*/
protected UserModel importValidation(RealmModel realm, UserModel user) {
if (user == null || user.getFederationLink() == null) return user;

UserStorageProviderModel model = getStorageProviderModel(realm, user.getFederationLink());
if (model == null) {
// remove linked user with unknown storage provider.
logger.debugf("Removed user with federation link of unknown storage provider '%s'", user.getUsername());
deleteInvalidUser(realm, user);
return null;
}

if (!model.isEnabled()) {
return new ReadOnlyUserModelDelegate(user) {
@Override
public boolean isEnabled() {
return false;
}
};
}

ImportedUserValidation importedUserValidation = getStorageProviderInstance(model, ImportedUserValidation.class, true);
if (importedUserValidation == null) return user;

UserModel validated = importedUserValidation.validate(realm, user);
if (validated == null) {
deleteInvalidUser(realm, user);
return null;
} else {
return validated;
}
}


On Wednesday, 10 November 2021 at 13:23:14 UTC+8 Hua Yao wrote:

Hua Yao

unread,
Jun 23, 2022, 10:31:25 AM6/23/22
to Keycloak Dev
hi .... 

got 6 user accounts were deleted in the last two days again. 
it's really not reliable. 




Hua Yao <hpya...@gmail.com> 于2022年6月11日周六 17:38写道:
--
You received this message because you are subscribed to the Google Groups "Keycloak Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to keycloak-dev...@googlegroups.com.

Marek Posolda

unread,
Jun 24, 2022, 5:30:46 AM6/24/22
to Hua Yao, Keycloak Dev
Hi,

What is your LDAP vendor? And what is the configuration of your LDAP provider in Keycloak? Could you please share especially the fields "Vendor" and "UUID LDAP attribute" from the configuration?

Just to explain, the field "UUID LDAP attribute" needs to contain some unique identifier of the user in the LDAP and unfortunately name of this attribute differs between LDAP vendors. For example Active Directory uses usually "objectGUID", some other servers use for example "entryUUID" . Alternative is to also use the attribute, which is mapped to username (like for example "uid" for some LDAP servers) as long as you can preserve the uniqueness and consistency of the users in your LDAP. For example if you delete user "john" from your LDAP and then create new user "john" in your LDAP, Keycloak may treat this as the same user (in case "UUID LDAP attribute" is configured to username attribute like "uid"), which may not be the correct approach.

Regards,
Marek

Hua Yao

unread,
Jun 24, 2022, 5:36:18 AM6/24/22
to Marek Posolda, Keycloak Dev
Hi Marek, 

thanks a lot for your replies. 

please kindly see the user federation configuration as below: 

Screenshot 2022-06-24 at 5.33.26 PM.png
Screenshot 2022-06-24 at 5.33.59 PM.png
Screenshot 2022-06-24 at 5.34.12 PM.png





Marek Posolda <mpos...@redhat.com> 于2022年6月24日周五 17:30写道:

Joaquim Fellmann

unread,
Jun 24, 2022, 8:26:05 AM6/24/22
to Hua Yao, Marek Posolda, Keycloak Dev
For Active Directory the RDN LDAP Attribute for the user objectclass is "cn" and not "samaccountname".
It's also probably a good idea to switch Search Scope to "Subtree" instead of "One Level" (in case user objects are later moved into a sub OU).
Additionally if your AD infrastructure is replicated you might want to check whether replication is working properly (in case Keycloak is hitting an LDAP instance that failed to replicate properly)

-- 
Joaquim Fellmann


Hua Yao

unread,
Jun 24, 2022, 8:28:20 AM6/24/22
to jfel...@fastmail.com, Keycloak Dev, Marek Posolda
Hi sir, thanks for the replies. 
Before we diversify the topic to the best practice. 

I am appreciate if we can focus on how to prevent keycloak delete the user randomly. 

🙏🏻

Marek Posolda

unread,
Jun 24, 2022, 9:06:50 AM6/24/22
to Hua Yao, jfel...@fastmail.com, Keycloak Dev
When Keycloak uses 3rd party user storage for storing the users (EG. LDAP), it tries to figure what users were removed from the LDAP. So in case that user is removed directly from the LDAP by LDAP administrator, Keycloak will figure that user is not available in the LDAP anymore and hence it will delete the user from Keycloak as well. This assumes that Keycloak is correctly configured to lookup users from LDAP.

Apart from the tips by Joaquim, I suggest to also doublecheck your "Custom User LDAP Filter" - unless the values like XXX are added just to hide the real values :-) You can also try to enable logging as described in the troubleshooting section: https://www.keycloak.org/docs/latest/server_admin/index.html#_ldap_troubleshooting . When you figure again that some user is deleted, it would be caused by the user was not found in LDAP, so you can doublecheck in the logs what queries were sent to the LDAP server right before and why it did not found the user in LDAP. Maybe it will help to find the root cause (if not already caused by the other issues above).

Marek

Hua Yao

unread,
Jun 24, 2022, 10:44:34 AM6/24/22
to Marek Posolda, jfel...@fastmail.com, Keycloak Dev
Thank you Marek, 

Sorry for the confusion, I just mask the domain with XXX. 

Pardon me, I cannot really link this issue with the LDAP filter. When there is no changes in the filter configuration and active director users, the search result should not be different. If the search result is the same, the UUID should be the same. should not keycloak treat it as the existing user? 

if the configuration and AD user is the same but search result is different, or if the search result is the same, but Keycloak deletes the user, doesnt sound like a bug? 

Thanks 





Marek Posolda <mpos...@redhat.com> 于2022年6月24日周五 21:06写道:

Marek Posolda

unread,
Jun 27, 2022, 2:50:26 AM6/27/22
to Hua Yao, jfel...@fastmail.com, Keycloak Dev
On 24. 06. 22 16:44, Hua Yao wrote:
Thank you Marek, 

Sorry for the confusion, I just mask the domain with XXX.
Yes, ok. I was thinking that "XXX" is probably just masking. Was just curious about doublecheck it.


Pardon me, I cannot really link this issue with the LDAP filter. When there is no changes in the filter configuration and active director users, the search result should not be different. If the search result is the same, the UUID should be the same. should not keycloak treat it as the existing user?
The problem is, that initially Keycloak searches for example by username (For example when you login with the particular user for the first time and you fill his username on the login form). At some next stage, the Keycloak verifies if user is still present in LDAP and hence it will search him by ID.


if the configuration and AD user is the same but search result is different, or if the search result is the same, but Keycloak deletes the user, doesnt sound like a bug?

Maybe yes, but will be good to confirm with some consistent steps to reproduce. Will be good if you enable the logging as pointed below to doublecheck what is going on. As pointed already, right before deletion of the user, there must be unsuccessful search to the LDAP server. So will be good if you figure what this LDAP query was and why it failed and if for example the same query passed previously for the same user.

Also will be good if you apply the other suggestions proposed by Joaquim (if you did not applied them already).

Hope it helps,
Marek

Hua Yao

unread,
Jun 27, 2022, 11:08:40 AM6/27/22
to Marek Posolda, Keycloak Dev, jfel...@fastmail.com
The problem is, if I change the filter now or I changed the UUID, all my production data will be gone. 
Cannot afford to the lost. 

Unfortunately, keycloak will also clear all local users if there is any changes in ldap connection. 
Reply all
Reply to author
Forward
0 new messages