以下の内容はhttps://kamatimaru.hatenablog.com/entry/2025/01/29/011639より取得しました。


PythonのKeycloakライブラリ「Python Keycloak」でAdmin REST APIを叩いてみる

概要

  • Keycloakには「Admin REST API」というREST APIが存在する
  • ただしアクセスするためには以下の2段階のフローが必要で使うのがやや面倒くさい仕様である
  • → この辺を隠蔽してくれるサードパーティライブラリがあったらうれしいと思い、アクティブに開発されていてStar数も700あるPython Keycloakというライブラリを試してみた。

github.com

検証

まずはPython Keycloakをインストールする

requirements.txt

python-keycloak==5.1.2
pip install -r requirements.txt

READMEの通りにようにKeycloakAdminインスタンスを作成する。

KeycloakAdminに渡すKeycloakOpenIDConnectionに必要な値は以下

  • server_url: KeycloakのベースURL
  • username: Admin権限を持つKeycloakのユーザーのユーザー名
  • password: Admin権限を持つKeycloakのユーザーのパスワード
  • realm_name: レルム名
  • client_id: Keycloakで払い出したクライアントID
  • client_secret_key: Keycloakで払い出したクライアントシークレット

main.py

from keycloak import KeycloakOpenIDConnection, KeycloakAdmin

keycloak_connection = KeycloakOpenIDConnection(
                        server_url="http://localhost/",
                        username='admin',
                        password='password',
                        realm_name="master",
                        client_id="testclient",
                        client_secret_key="***",
                        verify=True)

keycloak_admin = KeycloakAdmin(connection=keycloak_connection)

これでAdmin REST APIを叩く準備ができている。

続けて例えば以下のコードを追加して実行する。

# ...省略
print(keycloak_admin.get_user(user_id="7b898848-958f-4534-8459-764e916d72d5"))

すると以下のようにユーザー情報を取得できる。

$ python main.py
{
   "id":"7b898848-958f-4534-8459-764e916d72d5",
   "username":"admin",
   "email":"test@example.com",
   "emailVerified":true,
   "createdTimestamp":1738078594021,
   "enabled":true,
   "totp":false,
   "disableableCredentialTypes":[
      
   ],
   "requiredActions":[
      
   ],
   "notBefore":0,
   "access":{
      "manageGroupMembership":true,
      "view":true,
      "mapRoles":true,
      "impersonate":true,
      "manage":true
   }
}

アクセストークンの取得タイミング

先にも書いたが、KeycloakのAdmin REST APIは使う前に必ずアクセストークンを発行する必要がある。

従って、Python Keycloakはいつアクセストークンを発行しているのかが気になった。Keycloakの前段にリバースプロキシを置いて確認したところ、以下のタイミングではアクセスログが出力されなかった(=アクセストークンをまだ発行していない)

keycloak_admin.get_userを実行したときに以下の2つのアクセスログが出力された。1つ目がアクセストークンを発行するAPIへのリクエストである。

  1. POST /realms/master/protocol/openid-connect/token
  2. GET /admin/realms/master/users/7b898848-958f-4534-8459-764e916d72d5?...(省略)

ゆえに、アクセストークンの事前取得 & 永続化はしておらず、Admin REST APIを叩くメソッドを呼ぶたびに、都度アクセストークンを取得しにいく実装っぽいことが分かった。

実際のログ

proxy-1        | {"level":"info","ts":1738078832.4040802,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"192.168.97.1","remote_port":"58394","client_ip":"192.168.97.1","proto":"HTTP/1.1","method":"POST","host":"localhost","uri":"/realms/master/protocol/openid-connect/token","headers":{"Content-Type":["application/x-www-form-urlencoded"],"Content-Length":["153"],"User-Agent":["python-requests/2.32.3"],"Accept-Encoding":["gzip, deflate"],"Accept":["*/*"],"Connection":["keep-alive"]}},"bytes_read":153,"user_id":"","duration":0.093971635,"size":3551,"status":200,"resp_headers":{"X-Xss-Protection":["1; mode=block"],"Cache-Control":["no-store"],"Referrer-Policy":["no-referrer"],"X-Frame-Options":["SAMEORIGIN"],"Server":["Caddy"],"Strict-Transport-Security":["max-age=31536000; includeSubDomains"],"Pragma":["no-cache"],"Content-Length":["3551"],"X-Content-Type-Options":["nosniff"],"Content-Type":["application/json"]}}
proxy-1        | {"level":"info","ts":1738078832.410743,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"192.168.97.1","remote_port":"58396","client_ip":"192.168.97.1","proto":"HTTP/1.1","method":"GET","host":"localhost","uri":"/admin/realms/master/users/7b898848-958f-4534-8459-764e916d72d5?userProfileMetadata=False","headers":{"Content-Type":["application/json"],"Authorization":["REDACTED"],"User-Agent":["python-requests/2.32.3"],"Accept-Encoding":["gzip, deflate"],"Accept":["*/*"],"Connection":["keep-alive"]}},"bytes_read":0,"user_id":"","duration":0.003856672,"size":341,"status":200,"resp_headers":{"X-Frame-Options":["SAMEORIGIN"],"Content-Type":["application/json;charset=UTF-8"],"Server":["Caddy"],"Strict-Transport-Security":["max-age=31536000; includeSubDomains"],"X-Xss-Protection":["1; mode=block"],"Content-Length":["341"],"Cache-Control":["no-cache"],"Referrer-Policy":["no-referrer"],"X-Content-Type-Options":["nosniff"]}}

Admin REST APIKeycloakAdminのメソッド名の対応

実際には

  • やりたいことに適したAdmin REST APIを以下のドキュメントから探す
  • そのAPIに対応するKeycloakAdminのメソッドを探す

という使い方になりそうである。

urls_patterns.pyというファイルにAdmin REST APIのURLが定数で定義されている。従って、まずは使いたいAPIのURLと対応する定数をここから探すことになりそうである。

https://github.com/marcospereirampj/python-keycloak/blob/master/src/keycloak/urls_patterns.py

定数が分かったら、keycloak_admin.pyを定数でgrepすると使うべきメソッド名に辿り着けそうである。

https://github.com/marcospereirampj/python-keycloak/blob/master/src/keycloak/keycloak_admin.py




以上の内容はhttps://kamatimaru.hatenablog.com/entry/2025/01/29/011639より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14