Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get client secret in keycloak with admin user in different realm using python-keycloak

I have this workflow in place which works. I get a token from keycloak with admin username/password to this endpoint auth/realms/master/protocol/openid-connect/token With this token I request about client-secret of a specific client which is connected to another realms, not master. So, I request to this endpoint providing my brand new token in the header as bearer to this endpoint auth/admin/realms/realm_name/clients/client_name/client-secret And I can have client-secret With this client-secret I can get a client token requesting with client credentials to this endpoint auth/realms/realm_name/protocol/openid-connect/token And finally I use this client token to my stuff. I can use python-keycloak to get admin token

keycloak_admin = KeycloakAdmin(server_url=url,
                               username='user',
                               password='password',
                               verify=True)

But once I'm here, I cannot have client secret, due to my client is not in admin realm. Using browser with my regular admin, I can change between realms and accessing to other realm clients. And as I said, using a set of request to specific endpoints I can have what I want working, but I don't know how to do it using python-keycloak.

Thanks a lot for your help. I guess I've made my self clear enough.

Regards

like image 961
Xaruman Avatar asked Oct 14 '25 14:10

Xaruman


2 Answers

Maybe I am wrong, but I would expect that the following would work:

keycloak_admin = KeycloakAdmin(server_url=serv_url,
                               username='user',
                               password='pass',
                               realm_name='{realm_name}',
                               user_realm_name='master',
                               verify=True)

Get the client

client_id = keycloak_admin.get_client_id("{client_name}")

Get the Secret:

secret = keycloak_admin.get_client_secrets(client_id)
like image 95
dreamcrash Avatar answered Oct 17 '25 03:10

dreamcrash


I have this issue fixed. In case someone could be facing similar issues quite similar with requets strategy

Key is paying attention to required endpoint, if it's admin or openid

serv_url = "https://{keycloak_server}/auth/"
# Getting an admin token with admin user in master realm
keycloak_admin = KeycloakAdmin(server_url=serv_url,
                               username='user',
                               password='pass',
                               verify=True)
# Use that admin token to connect to other realm where client is located
insights_admin = KeycloakAdmin(server_url=serv_url,
                               realm_name='{realm_name}', client_id='{client_name}', verify=True,
                               custom_headers={
                                   'Authorization': 'Bearer ' + keycloak_admin.token.get('access_token'),
                                   'Content-Type': 'application/json'
                               })
# In order to get secret_key of acknowledge client, we neeed to request
# for keycloak id, not string name
client_id = insights_admin.get_client_id("{client_name}")
# With that id, we ca get client secret
secret = insights_admin.get_client_secrets(client_id)
# Finally with that client secret, we create a OpenID object as a regular
# "user" (client_name, secret_key), this is a little misleading, due to 
# here we need client_name again, not keycloak id, which is required to get 
# secret_key. In both cases, client_id is variable name to both methods
# but refer to different concepts 
insights_client = KeycloakOpenID(server_url=serv_url, realm_name='{realm_name}', client_id="{client_name}",
                                 client_secret_key=secret["value"], verify=True)
# And finally we ask for a token to identify that user, considering 
# KeycloakOpenID already has client_name, secret_key tuple to identify itself
# we just need to inform that we are going to use "client_credentials" instead
# of default password authentication
return insights_client.token(grant_type="client_credentials")

Being summarized looks pretty easy, but took me quite a while to deduce it. I hope someone could find it interesting and I could save some time to others.

like image 28
Xaruman Avatar answered Oct 17 '25 03:10

Xaruman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!