[keycloak-dev] [New feature idea] Add complex filtering to endpoints which are resposible for listing and counting users.

Marek Chmiel marochm at gmail.com
Tue Nov 7 11:01:35 EST 2017


*Current approach*

Currently the*/admin/realms/{realmName}/users* endpoint filter accepts the
following query string parameters:

*search, lastName, firstName, email, username, first, name*

The limitation is we cannot filter users by their custom attributes and
we cannot use complex filtering logic either.
Additionally, since the */**admin/realms/{realmName}**/users/count *accepts
no parameters,
we're unable to retrieve an actual count of all users matching certain
criteria.

*Improvement idea*

The idea is to support additional query string parameter when querying the
REST APIs
on */users* and */users/count* endpoints to manipulate the returned data
so that it is possible to filter user records by any custom attributes and
use complex filtering logic.

The example can be taken from OData spec's $filter attribute
<http://www.odata.org/documentation/odata-version-2-0/uri-conventions/#FilterSystemQueryOption>
or Forgerock OpenAM's filtering capabilities
<https://backstage.forgerock.com/docs/openam/13/dev-guide/#rest-api-filter-sort-page>
.
Both of this solutions introduce a filter parameter, the value of which is
basically a query DSL.

My suggestion is to implement the *$filter* query string parameter of the
following form to match user attributes:

*attribute operator value*

where *attribute *represents one of user's attributes, *operator *is the
operator code, *value *is the value to match.
The operators codes can be as follows:


   - For matching strings:


*equals *
*startswith *
*endswith *

*contains *
   - For matching other value types:

   *ge *- greater than or equal to
   *gt *- greater than
   *le *- less than or equal to
   *lt *- less than

Filters are read left-to-right.
Filters can be composed of multiple expressions by using boolean operators
*and*, *or*, *not *and by using parentheses, *(expression)* to group
expressions.
The *$filter* parameter must be URL-encoded.

I think it's possible to extend Keycloak with such a filter DSL because
underlying user storage is either SQL or LDAP based
and it's fairly easy to translate DSL query to either an SQL query or an
LDAP filter query.

Examples of filter values:

*firstName **startswith **Mar **and **age **gt **18*
*fullName **equals **"Mark Harmon" **or **myCustomLdapMappedAttribute *
*contains **customValue*

Is this something Keycloak might have implemented?
What you think, guys?


More information about the keycloak-dev mailing list