web-dev-qa-db-ja.com

クライアントシークレットを使用したKeyCloakの管理者の呼び出しREST API

https://keycloak.gitbooks.io/server-developer-guide/content/v/2.2/topics/admin-rest-api.html でCURLを使用する例は、からKeyCloakを実行するときに機能しますそのDockerイメージ。

アプリケーションの最終的なターゲットの形に移行するために、ユーザー名とパスワードではなく、クライアントIDとシークレットを使用して認証したいと思います。

ただし、admin-cliクライアントを「serviceaccounts enabled」に切り替えると、アクセスタイプは機密になり、次の呼び出しでトークンを取得します。

curl -d "client_id=admin-cli" -d "client_id=admin-cli" -d "client_secret=xxxx" -d "grant_type=client_credentials" "http://localhost:8080/auth/realms/master/protocol/openid-connect/token"

そのトークンは、admin REST APIへの呼び出しから403エラーになります。何か間違ったことをしましたか?

10
David North

Admin-cliにclient_credentialsを実装した方法は次のとおりです。

  1. あなたが言うように「サービスアカウント」を有効にする
  2. 「アクセスタイプ」を機密に設定します。これにより、client_secretを使用できるようになり、シークレットが割り当てられます([資格情報]タブ)。
  3. [サービスアカウント]タブで、サービスアカウントにレルム管理クライアントロールからレルム管理者ロールを付与します

特定のレルムの下でadmin-cliクライアントに対してこれを行っていたので、レルムを「マスター」から自分のレルム(私の場合はEEC-RLM)に変更できます。

http://192.168.101.139:8080/auth/realms/EEC-RLM/protocol/openid-connect/token

完全を期すために、admin uriを呼び出すときは、Authorizationヘッダーを「Beareraccess_token」に設定します。ここで、access_tokenは、上記の/ tokenuriから返されたaccess_tokenです。私の場合、私は次のように呼びます。

http://192.168.101.139:8080/auth/admin/realms/EEC-RLM/users

ドキュメントは、呼び出す実際のURLに関連する場合、必ずしも特に明確ではありません。たとえば、これらの操作は常にマスターレルムで行われると当初は思っていましたが、そうではありません。

6
Paul Duncan

このようなクライアントとして認証する場合、クライアントのサービスアカウントに適切な役割(「admin」など)を付与する必要があります。これは、クライアントのKeyCloak管理者の[サービスアカウントの役割]タブで実行できます。

3
David North

私は同じ問題を抱えていて、長い時間をかけてそれを理解しました(ところで、私はkeycloak v7.0.0を使用しています)。

これはあなたがする必要があることです:

  • 新しいconfidentialクライアントをレルムmasterに追加します
  • そのクライアントに対して、オプションService Accounts Enabledを有効にします
  • [マッパー]タブで、新しいカスタム「オーディエンス」マッパーを作成します:
    • 名前:aud-mapper
    • マッパータイプ:Audience
    • 含まれるクライアントオーディエンス:security-admin-console

次のようになります。

Custom Audience mapper

最後に、[サービスアカウントの役割]タブに移動し、役割 'admin'(または必要な役割)をクライアントサービスクライアントに割り当てます。

enter image description here

その後、クライアントに作成された管理トークンを取得して、管理者REST API。:

#!/usr/bin/env python
import requests
import json

headers = {"Content-Type": "application/x-www-form-urlencoded"}
url = "https://localhost:8080/auth/realms/master/protocol/openid-connect/token"
session = requests.Session()

grant_type='client_credentials'

client_id = "super-client"              # change this one
client_secret = "super-client-secret"   # change this one

payload = "scope=openid&client_id={0}&grant_type={1}&client_secret={2}".format(
            client_id, grant_type, client_secret)

ret = session.post(url=url, headers=headers, data=payload)
token_object = json.loads(ret.text)
print (token_object['access_token'])
1
dafero