How can I get userId after call create user api in keycloak?
Asked Answered
C

2

6

I implemented keycloak in my node.js project and call following API for add user in keycloak:

{{keycloak_url}}/admin/realms/{{realm}}/users

This API works and I can add user in keycloak but I need userId in response to this API how can I get this, any alternative way for this

Thanks in advance

Cerebellum answered 22/5, 2021 at 9:22 Comment(0)
C
4

Update: The /auth path was removed starting with Keycloak 17 Quarkus distribution. So you might need to remove the /auth from the endpoint calls presented on this answer.


You use the Keycloak Admin REST API endpoint GET /{realm}/users with the query parameter username. For instance:

GET "{{keycloak_url}}/auth/admin/realms/{{realm}}/users/?username={{username}}"

NOTE: In some Keycloak version it will return all the users with a username that matches {{username*}}. Therefore, you could use exact=true parameter to only fetch those matching {{username*}}. For those using bash script I have uploaded to my repo one example on how to do filter currently. From the response you just need to extract the field id.


The approach pointed out first by @Sillas Reis allows to create the user and get its ID in a single call, which is more performant. For those using bash and curl that solution could look like the following:

Call the Keycloak Admin REST API with an access token from a user with the proper permissions. For now, I will be using the admin user from the master realm:

curl “https://${KEYCLOAK_HOST}/auth/realms/master/protocol/openid-connect/token” \
    -d "client_id=admin-cli" \
    -d "username=${ADMIN_NAME}” \
    -d "password=${ADMIN_PASSWORD}" \
    -d "grant_type=password"

You get a JSON response with the admin's token. Extract the value of property access_token from that response. Let us save it in the variable $ACCESS_TOKEN for later reference.

To create the user in your realm $REALM_NAME and get back its id execute:

URL="https://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users/"
curl --include -X -s POST "${URL}" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $ACCESS_TOKEN" \
        -d "$USER_JSON" | grep "Location: ${URL}" | grep -o '[^/]\+$'

the flag --include will make curl include the headers, and the command grep "Location: ${URL}" will extract the location and the command grep -o '[^/]\+$' the user ID from that location.

Crossstaff answered 22/5, 2021 at 9:29 Comment(2)
Returning the URI of the newly created entity in the 'Location' header is not undocumented - it's part of the HTTP Specification. It's not documented explicitly because it's standard. See en.wikipedia.org/wiki/HTTP_location (and datatracker.ietf.org/doc/html/rfc7231#section-7.1.2)Nonie
@Nonie thanks for the piece of knowledge, I have remove that comment from the original answerCrossstaff
D
19

I believe there is another way to do this which will save you an extra request. If you take a look at the reponse headers when you create a user, you should find a field named "Location". It looks like this:

Location: http://keycloak_address/auth/admin/realms/realm/users/3a11cc77-9871-4f6e-805b-bf17ea79fa3a

In this case the value "3a11cc77-9871-4f6e-805b-bf17ea79fa3a" would be the new user's id.

Dionisio answered 13/12, 2021 at 13:37 Comment(0)
C
4

Update: The /auth path was removed starting with Keycloak 17 Quarkus distribution. So you might need to remove the /auth from the endpoint calls presented on this answer.


You use the Keycloak Admin REST API endpoint GET /{realm}/users with the query parameter username. For instance:

GET "{{keycloak_url}}/auth/admin/realms/{{realm}}/users/?username={{username}}"

NOTE: In some Keycloak version it will return all the users with a username that matches {{username*}}. Therefore, you could use exact=true parameter to only fetch those matching {{username*}}. For those using bash script I have uploaded to my repo one example on how to do filter currently. From the response you just need to extract the field id.


The approach pointed out first by @Sillas Reis allows to create the user and get its ID in a single call, which is more performant. For those using bash and curl that solution could look like the following:

Call the Keycloak Admin REST API with an access token from a user with the proper permissions. For now, I will be using the admin user from the master realm:

curl “https://${KEYCLOAK_HOST}/auth/realms/master/protocol/openid-connect/token” \
    -d "client_id=admin-cli" \
    -d "username=${ADMIN_NAME}” \
    -d "password=${ADMIN_PASSWORD}" \
    -d "grant_type=password"

You get a JSON response with the admin's token. Extract the value of property access_token from that response. Let us save it in the variable $ACCESS_TOKEN for later reference.

To create the user in your realm $REALM_NAME and get back its id execute:

URL="https://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users/"
curl --include -X -s POST "${URL}" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $ACCESS_TOKEN" \
        -d "$USER_JSON" | grep "Location: ${URL}" | grep -o '[^/]\+$'

the flag --include will make curl include the headers, and the command grep "Location: ${URL}" will extract the location and the command grep -o '[^/]\+$' the user ID from that location.

Crossstaff answered 22/5, 2021 at 9:29 Comment(2)
Returning the URI of the newly created entity in the 'Location' header is not undocumented - it's part of the HTTP Specification. It's not documented explicitly because it's standard. See en.wikipedia.org/wiki/HTTP_location (and datatracker.ietf.org/doc/html/rfc7231#section-7.1.2)Nonie
@Nonie thanks for the piece of knowledge, I have remove that comment from the original answerCrossstaff

© 2022 - 2024 — McMap. All rights reserved.