Access to Keycloak REST API fails

I try to figure out and without any success why the end-point to get the realm users fails:

curl -X GET -i http://localhost:8080/auth/demo/users

I’m getting:

{"error":"RESTEASY003210: Could not find resource for full path: http://localhost:8080/auth/demo/users"}

I created a realm named demo and a single user user1.

What am I missing?

Keycloak API base path is /auth/admin/realms

So, in your casse, try with http://localhost:8080/auth/admin/realms/demo/users

2 Likes

Weird enough because the API docs say about the base URL:
“Host: localhost:8080 BasePath: /auth Schemes: HTTP”.


And I found nowhere the end-point docs you posted.

Second point, when testing you URL with curl -X GET -i http://localhost:8080/auth/admin/realms/demo/users I got the 401 response:

HTTP/1.1 401 Unauthorized
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Referrer-Policy: no-referrer
Date: Wed, 16 Sep 2020 06:38:28 GMT
Connection: keep-alive
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
Content-Type: application/json
Content-Length: 33

{"error":"HTTP 401 Unauthorized"}%    

You are correct, keycloak rest api docs need to be improved (https://issues.redhat.com/browse/KEYCLOAK-7966 ).

Forget /auth and always use /auth/admin/realms as base path.

And you get 401 response because of Authorization header isn’t in your request.
Use --header option as it below.

curl -H "Authorization: bearer {YOUR_ACCESS_TOKEN}" "http://localhost:8080/auth/admin/realms/demo/users"

1 Like

Thank you for your response.
This is at least frustrating to have the outdated documentation :(. The issue was created 2 years ago and still assigned to nobody and sure, not fixed. More of that, I have to figure out how to get a token from Keycloak to be able to hit the end-point you indicated and adapt all the API end-points URLs to make it work :(.

Hello All,

I am getting below error on Get api.
Post i got Token but once i am trying to get with this tokent saying “error”: “HTTP 401 Unauthorized”.

this is my Get url: http://localhost:8080/auth/admin/realms/education/users

I dont know what is the issue. Could anyone help me on this ?

Could you elaborate how did you get a token?

Option1: Service Accounts

You need to toggle Service Account Enabled button in the client application settings and then you can get a token using client_credentials grant.

Let’s get token using the below curl command:

curl --location --request POST 'http://localhost:8181/auth/realms/education/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic base64(clientId:clientSecret)' \
--data-urlencode 'grant_type=client_credentials'

language-json

Response

{
    "access_token": "a jwt token",
    "expires_in": 300,
    "refresh_expires_in": 0,
    "token_type": "Bearer",
    "not-before-policy": 0,
    "scope": "email profile"
}

language-json

Note: this token is one time token and can’t be refreshed.
Let’s assign a functionality “ view-users ” and “manage-users” to the service account.
We can find this role under “Client Roles” → Realm-management
Click on “view-users”, “manage-users” Role in available roles and assign it to the service account as shown in the image below. This will assign the role of viewing the user list and managing the users to the our client application in the keycloak realm “education”.

Let’s create a user with the token we got above:

curl --location --request POST 'http://localhost:8181/auth/admin/realms/education/users' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{access_token}}' \
--data-raw '{
        "createdTimestamp": 1588880747548,
        "username": "samir",
        "enabled": true,
        "totp": false,
        "emailVerified": true,
        "firstName": "fName",
        "lastName": "Lname",
        "email": "someemail@gmail.com",
        "disableableCredentialTypes": [],
        "requiredActions": [],
        "notBefore": 0,
        "access": {
            "manageGroupMembership": true,
            "view": true,
            "mapRoles": true,
            "impersonate": true,
            "manage": true
        },
        "realmRoles": [	"mb-user" ]
    }'

language-json

Response
201 Created.

Let’s get the user list :

curl --location --request GET 'http://localhost:8181/auth/admin/realms/education/users' \
--header 'Authorization: Bearer {{access_token}}'

language-json

Response

[
    {
        "id": "047add83-d1de-456a-b0a7-8480292fb769",
        "createdTimestamp": 1635842744523,
        "username": "adf",
        "enabled": true,
        "totp": false,
        "emailVerified": true,
        "firstName": "sdf",
        "lastName": "sdf",
        "email": "somemail@gmail.com",
        "disableableCredentialTypes": [],
        "requiredActions": [],
        "notBefore": 0,
        "access": {
            "manageGroupMembership": true,
            "view": true,
            "mapRoles": true,
            "impersonate": false,
            "manage": true
        }
    }
]

language-json

Thus, we have tested the functionality of getting the list of users in the realm by means of service account. Similarly, we can perform various other functions using the service accounts.
Option2 :

We can also achieve the same behavior bu using password grant type and a user with a proper role mapping.So having a client application is required but without service account enabled.

Get token request :

curl --location --request POST 'http://localhost:8181/auth/realms/education/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic base64(clientId:clientSecret)' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=uname' \
--data-urlencode 'password=pass'

language-json

Response:

{
    "access_token": "a jwt token",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "refresh jwt token ",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "6df504f6-399a-4efd-a23e-067b161e5911",
    "scope": "email profile"
}

language-json

After getting access token we can fetch the users using the same token.

curl --location --request GET 'http://localhost:8181/auth/admin/realms/fyrefish-dev/users' \
--header 'Authorization: Bearer {{access_token}}'

language-json

Conclusion

For the Option1 creating user and user session is not required, just having a client application with service accounts enabled will do the things for us .(of course proper roles will be required depending on use case, view/manage users etc).

For the Option2 - we will need a client application + a user with credentials and the proper role mapping. Once we execute /token request keycloak server will create a session for this user.

Hello Samir.aghayarov,

Thank you very much for your replay and help, but i am fully new to keycloak and codding part, so its possible may i have your contact number or mail id so some query which i have i can share with you please samir

I am happy to help ,I would ask you share questions here publicly so everyone can benefit in the future.

Thank you samir, but my question is not fully with technically or some basic basic questions i have, so plese help me with your mail id or number if passible please

Samir,

I need to implement one funcation in keyclaok user registration page, OTP and Email verification.
Once user click on sumbit button he should get 4 digit code on his mobile number and email verification link in his email id.
So email i did but i am not getting for sam otp. how to do this codding and add this funcation.

Could you help me on this ?
Please

you there Samir if possible please replay on above query

Maybe i was late. After hours fighting with keycloak. In my version 17.1 (April, 2022), to create user the URL Path are

http://:8080/admin/realms//users

(yes, I not use auth in path, in these case throw me the error: “RESTEASY003210: Could not find resource for full path: http://:8080/auth/admin/realms//users”)

Headers

Authorization: Bearer <token>
Content-Type: application/json

Body: type raw
{"enabled":true,"username":"rperez","email":"rperez@gmail.com","firstName":"raton","lastName":"perez","credentials":[{"type":"password","value":"12345","temporary":false}]}