pythonrealmkeycloak

"Invalid_grant" error after using "change_current_realm()" in keycloak-python


I have 401: b'{"error":"invalid_grant","error_description":"Invalid user credentials"}' error after I switch realm with change_current_realm() function from "master" to "new-sso" realm.

Here is the full code:

from keycloak import KeycloakAdmin
from keycloak import KeycloakOpenIDConnection

server_url = "http://localhost:8080/"
new_sso_relam = "new-sso"

admin_username = 'admin'
admin_password = 'admin'
admin_client = 'admin-cli'
master_realm = "master"

keycloak_connection = KeycloakOpenIDConnection(server_url=server_url, 
                                                username=admin_username, 
                                                password=admin_password, 
                                                client_id=admin_client, 
                                                realm_name=master_realm)
keycloak_admin = KeycloakAdmin(connection=keycloak_connection)

keycloak_admin.change_current_realm(new_sso_relam)

user_payload = {"username": "new_user",
    "enabled": True}

keycloak_admin.create_user(user_payload, exist_ok=True)  

However if before switching to "new-realm" I call keycloak_admin.get_realm(master_realm), then the code works fine and I can create user.

keycloak_admin.get_realm(master_realm)

keycloak_admin.change_current_realm(new_sso_relam)
user_payload = {"username": "new_user",
    "enabled": True}

keycloak_admin.create_user(user_payload, exist_ok=True)  

I belive the invalid_grant error indicates that after switching realms with change_current_realm(), the credentials I'm using are no longer valid for the new realm. This issue arises because the Keycloak Admin client (in this case, admin-cli) is authenticated against the "master" realm and does not automatically carry over those credentials to the "new-sso" realm.

When I call keycloak_admin.get_realm(master_realm), it seems to refresh or validate your session, allowing you to switch to the new realm successfully. However, you want to eliminate that extra step.


Solution

  • You need to add user_realm_name=master_realm in KeycloakOpenIDConnection()

    keycloak_connection = KeycloakOpenIDConnection(server_url=server_url, 
                                                    username=admin_username, 
                                                    password=admin_password, 
                                                    client_id=admin_client, 
                                                    realm_name=master_realm,
                                                    user_realm_name=master_realm)
    

    Launching Keycloak

    docker-compose in here

    Create new-sso realm by UI

    new-sso enter image description here

    Demo code

    create-user.py

    from keycloak import KeycloakOpenIDConnection, KeycloakAdmin
    
    server_url = "http://localhost:8080/"
    new_sso_relam = "new-sso"
    
    admin_username = 'admin'
    admin_password = 'admin'
    admin_client = 'admin-cli'
    master_realm = "master"
    
    keycloak_connection = KeycloakOpenIDConnection(server_url=server_url, 
                                                    username=admin_username, 
                                                    password=admin_password, 
                                                    client_id=admin_client, 
                                                    realm_name=master_realm,
                                                    user_realm_name=master_realm)
    
    keycloak_admin = KeycloakAdmin(connection=keycloak_connection)
    
    keycloak_admin.change_current_realm(new_sso_relam)
    
    user_payload = {"username": "new_user","enabled": True}
    keycloak_admin.create_user(user_payload, exist_ok=True)
    print("new_user registered")
    

    Dependency

    pip install python-keycloak
    

    enter image description here

    Run it

    enter image description here

    Result

    enter image description here