Keycloak ignores realmRoles when adding a user by rest api

When I am creating a new user by using Keycloak rest API, the application ignores the realmRoles property not assigning the role to the new user. Here is an exemple

POST: https://localhost:8543/auth/admin/realms/quarkus/users

Body:
{
   "username":"alexandre",
   "enabled":true,
   "emailVerified":true,
   "firstName":"Alexandre",
   "lastName":"Oliveira",
   "email":"alexandreqogmailcom",
   "credentials":[
      {
         "type":"password",
         "value":"123456",
         "temporary":false
      }
   ],
   "realmRoles":[
      "user_esc"
   ],
   "access":{
      "mapRoles":true
   }

Is there a way to resolve this problem or a work around ?

PS: I am using the keycloak version 12.0.1

Upvotes: 2

Views: 1191

Answers (2)

Abel
Abel

Reputation: 798

Thanks to @dreamcrash answer I was able to make a python function for this. I'm sharing in case someone else needs it.

It requires the following dependency: requests


BASE_URL = "http://localhost:8081"
REALM_ID = "toto"
REALM_NAME = "toto"

def get_token() -> str:
    resp = requests.post(
        url=f"{BASE_URL}/realms/master/protocol/openid-connect/token",
        data={
            "client_id": "admin-cli",
            "username": "admin",
            "password": "admin",
            "grant_type": "password",
        },
    )
    access_token = resp.json()["access_token"]
    logging.info(f"access_token: {access_token}")
    return access_token

def create_user(session: Session, email: str, role_name: str | None = None):
    # Create user
    url = f"{BASE_URL}/admin/realms/{REALM_ID}/users/"
    request_body = {
        "email": email,
        "username": email,
        "emailVerified": True,
        "enabled": True,
    }
    data = json.dumps(request_body)
    resp = session.post(url, data=data)

    # get user id
    url = f"{BASE_URL}/admin/realms/{REALM_ID}/users/?username={email}"
    resp = session.get(url)
    user_id = resp.json()[0]["id"]

    # get role id
    # GET: https://localhost:8543/auth/admin/realms/quarkus/roles/<ROLE_NAME>
    url = f"{BASE_URL}/admin/realms/{REALM_ID}/roles/{role_name}"
    resp = session.get(url)
    role_id = resp.json()["id"]

    # create role-mapping
    url = f"{BASE_URL}/admin/realms/{REALM_ID}/users/{user_id}/role-mappings/realm"
    request_body = [{"id":role_id,"name":role_name}] 
    data = json.dumps(request_body)
    resp = session.post(url, data=data)

ACCESS_TOKEN = get_token()
session = Session()
session.headers.update({"Content-Type": "application/json"})
session.headers.update({"Authorization": f"Bearer {ACCESS_TOKEN}"})

create_user(
        session=session,
        email="[email protected]",
        role_name="toto-admin",
    )


Upvotes: 2

dreamcrash
dreamcrash

Reputation: 51393

If you are expecting that with the endpoint:

POST: https://localhost:8543/auth/admin/realms/quarkus/users

it will also create the realm roles, that will not happen, it will not create the Realm roles. To create the Realm roles you either use the Admin Console or you use the endpoint:

POST https://localhost:8543/auth/admin/realms/quarkus/roles

with the payload

{"name":"<ROLE_NAME>","description":"<DESCRIPTION>"}

if it is a non Composite Realm Role.

To assign the Realm Role to the user, after having create the user, call the endpoint:

POST: https://localhost:8543/auth/admin/realms/quarkus/users/<USER_ID>/role-mappings/realm

with the payload

[{"id":"<Role ID>","name":"<Role Name>"}] 

The role ID you can get it from:

GET: https://localhost:8543/auth/admin/realms/quarkus/roles/<ROLE_NAME>

and the user ID from :

GET: https://localhost:8543/auth/admin/realms/quarkus/users/?username=<USERNAME>

I have upload the following bash scripts to automatize this process.

Upvotes: 3

Related Questions