keycloak / keycloak

Open Source Identity and Access Management For Modern Applications and Services
https://www.keycloak.org
Apache License 2.0
23.4k stars 6.77k forks source link

Query with q Parameter returns Http 400 (Bad Request) #22578

Closed beye-pelz closed 1 year ago

beye-pelz commented 1 year ago

Before reporting an issue

Area

admin/api

Describe the bug

We use our KeyCloak Instance with an LDAP IDP. From there we get the custom attribute employeeNumber. When I count the items for employeeNumber via: /auth/admin/realms/realm/users/count?q=employeeNumber:123456 it returns 1, which is correct. When now try to load the Users details via: /auth/admin/realms/realm/users?q=employeeNumber:123456 it return http status 400.

It all started after Upgrading from Keycloak Version 21.1.2 to 22.0.1. I check the documentation here: https://www.keycloak.org/docs-api/22.0.1/rest-api/index.html#_users When I'm right nothing has changed, so the behaviour under 21.1.2 should still be the same in 22.0.1.

Version

22.0.1

Expected behavior

When I load the users details with a q parameter and a custom attribute, I want to get the user/users and no http status 400

Actual behavior

Currently I get a http status 400 when I try to load the user Details with an q parameter.

How to Reproduce?

Add an custom attribute and try to search for it.

Anything else?

No response

sschu commented 1 year ago

I cannot reproduce this. When I try your example, I get a 200 but the "q=employeeNumber:" is essentially ignored, so I get all users. I assume passing only key and colon but no value is not the intended usage. The code here just seems to ignore keys with empty values: https://github.com/keycloak/keycloak/blob/a7e014fbb7f0c181f73000ccd63480c416000abd/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java#L944 The behaviour also has not changed, I tested this with Keycloak 21.1.2 as well.

beye-pelz commented 1 year ago

I cannot reproduce this. When I try your example, I get a 200 but the "q=employeeNumber:" is essentially ignored, so I get all users. I assume passing only key and colon but no value is not the intended usage. The code here just seems to ignore keys with empty values:

https://github.com/keycloak/keycloak/blob/a7e014fbb7f0c181f73000ccd63480c416000abd/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java#L944

The behaviour also has not changed, I tested this with Keycloak 21.1.2 as well.

Hi, I updated my comment. The html excape removed some-essential parts. The value ist not meant to be empty, I'm passing the employee Number and I still get the full list, or to be more specific, the 100 first Users, as it is the default max. But I don't get the filtered result. Hope this helps to clarify my problem.

sschu commented 1 year ago

I still cannot reproduce this, I just tested your scenario and I correctly get only one user with the given employeeNumber out of the two existing, see screenshot: Screenshot 2023-08-23 at 15 22 58

beye-pelz commented 1 year ago

Hi,

I now started from scratch and tested like you did. I can confirm, then it works fine.

Then updated my new installtion to our production standard and added an ldap/active directory. For this users I'm not able to search for the employeeNumber.

For Version 21.1.2 i can't use this approche to test, cause the ui doesn't have the ability to search for attributes. There only the original api, I used is available.

Maybe this also helps, I'm using Spring WebClient to access the API.

sschu commented 1 year ago

When I look at https://github.com/keycloak/keycloak/blob/535bba57928c1313d964b15d7578bf22f02114b3/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProvider.java#L421-L444. , it does not look like searching for arbitrary attributes actually works for LDAP.

beye-pelz commented 1 year ago

I tested it again with Version 21.1.2 and it works fine. Then I tested with Version 22.0.1 and I get http status 400.

I consent, that the code you provided, in neither Version is doing something with the params.

Anyway, the behaviour changed between 21.1.2 and 22.0.1.

Most strange for me is, that the count is working, only the loading of the actual users fails.

sschu commented 1 year ago

Are you importing the users from LDAP? Maybe the operation actually searches the database but not the LDAP? In any case, a minimal reproducer would be necessary to make progress here.

beye-pelz commented 1 year ago

Yes, we are syncing the Users. What execatly do you need for an minimal reproducer, cause I can't give access to our Active Directory?

sschu commented 1 year ago

A setup I can replicate so I can replicate the problem. If that is too complicated, you can also try to analyze yourself why it does not work anymore for example by attaching a debugger and following the respective code.

rmartinc commented 1 year ago

@beye-pelz As @sschu commented, I can only replicate your behavior if the users are not imported in the internal DB (option "Import users" to OFF in the ldap provider). But if I have the option to ON the user is searched OK, the internal DB is used in that case. The reason is that the ldap provider only searches for certain attributes.

I have tested with 21.1.2 and the only difference is that in the old version, when failing, import users to OFF, it returns 0 results and now it returns all users. That's because of https://github.com/keycloak/keycloak/issues/17294.

rmartinc commented 1 year ago

@beye-pelz Do you get something in order we can reproduce this?

As commented I have never seen error 400, I always get 200. There is a different behavior when "Import users" is OFF between version 21 and 22 but it's because https://github.com/keycloak/keycloak/issues/17294.

rmartinc commented 1 year ago

@beye-pelz @sschu I'm closing this as we cannot reproduce the issue. I never see a 400. There is a different behavior between 21 and 22 when users are not imported into the DB, but that is explained by #17294. If someone finds the exact reproducer steps to show the error please re-open or file a new issue.