[keycloak-dev] Support case sensitive usernames

Marek Posolda mposolda at redhat.com
Fri Sep 6 11:16:15 EDT 2019


At this moment, Keycloak internally saves all usernames in the DB in 
lowercase. This means that if Keycloak DB contains user "john" and user 
fills the login form with uppercase like "John", Keycloak is still able 
to find the user because it lowercase the username from the login form 
to "john" and then query DB for lookup of username "john" . At the same 
time, DB queries have good performance as they are not needed to be case 
sensitive.

Also when we import users from the 3rd party user storage like ldap, we 
first convert them to lowercase. Unfortunately this causes issues for 
some users, as they have LDAP users in uppercase like "JOHN" and 
usernames in keycloak tokens are returned in lowercase like "john", 
which causes issues in some applications.

I see 2 possibilities to address this issue:

1) Have a switch at the realm level to support case-sensitive usernames
2) Address this issue at LDAP level and add special attribute to users 
imported from LDAP

More details:

The solution (1) has some more flexibility and is not LDAP specific, 
however it may either have non-trivial performance penalty due the 
case-sensitive DB searches or it may mean possibility of duplicated 
usernames different just by cases like "john", "John" and "JOHN".

I can imagine that switch at realm level will have 3 options similar to 
this:

  * (a) Don't support case insensitive usernames (default value and
    current behaviour). So usernames are lowercased before saving to
    Keycloak DB and before DB searches.
  * (b) Support case sensitive usernames with case-sensitive duplicated
    users. If this option is chosen, it will be possible to have for
    example 3 separate Keycloak users like "mposolda", "Mposolda" and
    "MPOSOLDA". This will mean that users will need to fill exactly
    their case-sensitive username on the login form
  * (c) Support case sensitive usernames without case-sensitive
    duplicated users. If this option is chosen, you will have
    case-sensitive user saved in the DB, however it won't be allowed to
    have duplicated usernames different just by cases. So you won't be
    able to have "mposolda", "Mposolda" and "MPOSOLDA". The third option
    has price-to-pay as DB searches will need to be case-sensitive and
    hence may have quite bad performance as mentioned for example in
    this blog:
    https://alvinalexander.com/sql/sql-select-case-insensitive-query-queries-upper-lower
    . I am not even convinced whether to ever support this option, I
    rather vote for no. Performance may be better once we move away from
    RDBMS to Keycloak.next storage, but not sure.

2) Address this issue at LDAP level and add special attribute to users 
imported from LDAP. That will allow that LDAP user "MPOSOLDA" can be 
mapped to Keycloak user "mposolda". At the Keycloak level, the user 
"mposolda" will have the attribute like LDAP_USERNAME with the value 
"MPOSOLDA" . In this case, people may need to create protocol mapper, 
which will map the LDAP_USERNAME attribute to their token. Protocol 
mapper can be added to client scope, which can be added to all required 
clients. Not sure if this is workaround or not

So far, I vote for (1) and maybe just add the (a) and (b) options. WDYT?

Marek


More information about the keycloak-dev mailing list