12671 querying by user attribute no longer forces case insensitivity for keys

Signed-off-by: Sebastian Schuster <sebastian.schuster@bosch.io>
This commit is contained in:
Sebastian Schuster 2024-03-13 17:42:01 +01:00 committed by Pedro Igor
parent 2acb5c1d2a
commit 0542554984
4 changed files with 12 additions and 5 deletions

View file

@ -4,4 +4,8 @@ The following methods for setting custom cookies have been removed:
* `LocaleSelectorProvider.KEYCLOAK_LOCALE` - replaced by `CookieType.LOCALE`
* `HttpCookie` - replaced by `NewCookie.Builder`
* `HttpResponse.setCookieIfAbsent(HttpCookie cookie)` - replaced by `HttpResponse.setCookieIfAbsent(NewCookie cookie)`
* `HttpResponse.setCookieIfAbsent(HttpCookie cookie)` - replaced by `HttpResponse.setCookieIfAbsent(NewCookie cookie)`
= Searching by user attribute no longer case insensitive
When searching for users by user attribute, Keycloak no longer searches for user attribute names forcing lower case comparisons. The goal of this change was to speed up searches by using Keycloak's native index on the user attribute table. If your database collation is case-insensitive, your search results will stay the same. If your database collation is case-sensitive, you might see less search results than before.

View file

@ -30,3 +30,7 @@ The module `org.keycloak:keycloak-model-legacy` module was deprecated in a previ
= Removed offline session preloading
The old behavior to preload offline sessions at startup is now removed after it has been deprecated in the previous release.
= Removing custom user attribute indexes
When searching for users by user attribute, Keycloak no longer searches for user attribute names forcing lower case comparisons. This means Keycloak's native index on the user attribute table will now be used when searching. If you have created your own index based on `lower(name)`to speed up searches, you can now remove it.

View file

@ -1001,15 +1001,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
// All unknown attributes will be assumed as custom attributes
default:
Join<UserEntity, UserAttributeEntity> attributesJoin = root.join("attributes", JoinType.LEFT);
if (value.length() > 255) {
customLongValueSearchAttributes.put(key, value);
attributePredicates.add(builder.and(
builder.equal(builder.lower(attributesJoin.get("name")), key.toLowerCase()),
builder.equal(attributesJoin.get("name"), key),
builder.equal(attributesJoin.get("longValueHashLowerCase"), JpaHashUtils.hashForAttributeValueLowerCase(value))));
} else {
attributePredicates.add(builder.and(
builder.equal(builder.lower(attributesJoin.get("name")), key.toLowerCase()),
builder.equal(attributesJoin.get("name"), key),
builder.equal(builder.lower(attributesJoin.get("value")), value.toLowerCase())));
}
break;

View file

@ -927,7 +927,7 @@ public class UserTest extends AbstractAdminTest {
createUsers();
Map<String, String> attributes = new HashMap<>();
attributes.put("attr", "common");
attributes.put("attr", "Common");
for (int i = 1; i < 10; i++) {
List<UserRepresentation> users = realm.users().searchByAttributes(i - 1, 1, null, false, mapToSearchQuery(attributes));
assertEquals(1, users.size());