如何使用 python-keycloak 在不同领域的管理员用户的密钥斗篷中获取客户端机密

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

我有这个有效的工作流程。 我从带有管理员 username/password 的 keycloak 得到一个令牌到这个端点 auth/realms/master/protocol/openid-connect/token 使用此令牌,我请求连接到另一个领域的特定客户端的 client-secret,而不是主服务器。因此,我请求此端点在 header 中提供我的全新令牌作为此端点 auth/admin/realms/realm_name/clients/client_name/client-secret 的承载者 我可以 client-secret 有了这个 client-secret 我可以得到一个客户端令牌请求客户端凭据到这个端点 auth/realms/realm_name/protocol/openid-connect/token 最后我将这个客户端令牌用于我的东西。 我可以使用 python-keycloak 获取管理令牌

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

但是一旦我到了这里,我就无法拥有客户机密,因为我的客户不在管理领域。通过我的常规管理员使用浏览器,我可以在领域之间切换并访问其他领域客户端。正如我所说,使用一组对特定端点的请求我可以得到我想要的工作,但我不知道如何使用 python-keycloak.

非常感谢您的帮助。我想我已经说得很清楚了。

此致

我已经解决了这个问题。以防有人遇到类似问题

Key 正在关注所需的端点,如果是 admin 或 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")

归纳起来看起来很容易,但推导起来却花了我不少时间。我希望有人会觉得它有趣,我可以为其他人节省一些时间。

也许我错了,但我希望以下方法可行:

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

获取客户​​端

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

获取秘密:

secret = keycloak_admin.get_client_secrets(client_id)