Skip to content

python-keycloak で Keycloak の操作を自動化する

python-keycloak を使うと Keycloak の操作をプログラムから自動化することが出来ます。 今回は python-keycloak の基本的な使い方をメモしておきます。 検証は RockyLinux8 と Python 3.9.6 で実施しました。

Keycloak 自体の REST API ガイドは Keycloak Admin REST API にあるものの、現時点で python-keycloak のドキュメントはあまり充実しておらず、keycloak_admin.py のソースコード などを直接、読んだ方が理解が進みそうです。

Keycloak コンテナを起動する

Keycloak を docker で起動する に記載した方法で docker を使い、Keycloak のコンテナを起動します。 まず docker をインストールします。

1
2
3
4
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker

Keycloak コンテナを起動します。

1
2
3
4
5
6
7
docker run \
  -d \
  -p 8080:8080 \
  -e KEYCLOAK_USER=admin \
  -e KEYCLOAK_PASSWORD=password \
  --name keycloak \
  jboss/keycloak

Python3 のインストール

Python3 をインストールしておきます。

1
2
dnf install -y python39
alternatives --set python /usr/bin/python3.9

python-keycloak のインストール

venv 環境を作成して python-keycloak をインストールします。

1
2
3
4
5
6
mkdir sample
cd sample
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install python-keycloak

サンプルスクリプト

ユーザ関連

ユーザを作成する (パスワード無し)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

new_user = keycloak_admin.create_user(
    {
        "email": "user1@example.com",
        "username": "user1",
        "enabled": True,
        "firstName": "Foo",
        "lastName": "Bar",
    }
)

ユーザを作成する (パスワード有り)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

new_user = keycloak_admin.create_user(
    {
        "email": "user1@example.com",
        "username": "user1",
        "enabled": True,
        "firstName": "Foo",
        "lastName": "Bar",
        "credentials": [
            {
                "value": "secret",
                "type": "password",
            }
        ],
    }
)

ユーザを作成する (パスワード有り / jp ロケール指定)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

new_user = keycloak_admin.create_user(
    {
        "email": "user1@example.com",
        "username": "user1",
        "enabled": True,
        "firstName": "Foo",
        "lastName": "Bar",
        "credentials": [
            {
                "value": "secret",
                "type": "password",
            }
        ],
        "attributes": {"locale": ["jp"]},
    }
)

ユーザ一覧を取得する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
import json

from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

results = keycloak_admin.get_users({})
print(json.dumps(results, indent=2))

ユーザを削除する

delete_user() はユーザ ID を引数に指定出来ますが、ユーザ名を指定することが出来ません。 その為、先に get_user_id() でユーザ ID を取得してから delete_user() を呼び出します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

user_id = keycloak_admin.get_user_id("user1")
response = keycloak_admin.delete_user(user_id)

Realm 関連

Realm を作成する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

keycloak_admin.create_realm(
    payload={"realm": "realm1", "enabled": True}, skip_exists=True
)

Relam を作成する (パラメータ指定)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

keycloak_admin.create_realm(
    payload={
        "realm": "realm1",
        "enabled": True,
        "registrationAllowed": True,
        "resetPasswordAllowed": True,
        "rememberMe": True,
    },
    skip_exists=True,
)

file

Realm を作成する (SSL/TLS 接続を無効化)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

keycloak_admin.create_realm(
    payload={"realm": "realm1", "enabled": True, "sslRequired": "none"},
    skip_exists=True,
)

file

Realm の設定を更新する (master Realm)

keycloak_admin.pyupdate_relam で定義されていますが、update_realm は第一引数に Realm 名を指定します (Payload で Realm 名を指定しません)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

keycloak_admin.update_realm(
    "master",
    payload={
        "enabled": True,
        "registrationAllowed": True,
        "sslRequired": "none",
        "resetPasswordAllowed": True,
        "rememberMe": True,
    },
)

Realm 一覧を取得する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
import json

from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

result = keycloak_admin.get_realms()
print(json.dumps(result, indent=2))

OpenID Endpoint Configuration (Well Know 情報) 関連

Well Know 情報を取得する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env python3
import json

from keycloak import KeycloakOpenID

keycloak_openid = KeycloakOpenID(
    server_url="http://localhost:8080/auth/",
    client_id="admin_cli",
    realm_name="master",
    client_secret_key="",
)

result = keycloak_openid.well_know()
print(json.dumps(result, indent=2))

Well Know 情報から issuer を取得する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/env python3
from keycloak import KeycloakOpenID

keycloak_openid = KeycloakOpenID(
    server_url="http://localhost:8080/auth/",
    client_id="admin_cli",
    realm_name="master",
    client_secret_key="",
)

data = keycloak_openid.well_know()
print(data["issuer"])

クライアント関連

クライアント一覧を取得する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

results = keycloak_admin.get_clients()
print(json.dumps(results, indent=2))

クライアント ID を取得する

クライアント名からクライアント ID を取得します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

client = keycloak_admin.get_client_id("admin-cli")
print(client)

クライアントを作成する (Access Type = public)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python3
from keycloak import KeycloakAdmin, KeycloakOpenID

URL = "http://localhost:8080/auth/"

keycloak_openid = KeycloakOpenID(
    server_url=URL,
    realm_name="master",
    client_id="admin-cli",
    client_secret_key="",
)

issuer = keycloak_openid.well_know()["issuer"]

keycloak_admin = KeycloakAdmin(
    server_url=URL,
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

client = keycloak_admin.create_client(
    payload={
        "clientId": "client1",
        "publicClient": True,
        "redirectUris": [issuer],
    },
    skip_exists=True,
)

クライアントを作成する (Access Type = confidential)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python3
from keycloak import KeycloakAdmin, KeycloakOpenID

URL = "http://localhost:8080/auth/"

keycloak_openid = KeycloakOpenID(
    server_url=URL,
    realm_name="master",
    client_id="admin-cli",
    client_secret_key="",
)

issuer = keycloak_openid.well_know()["issuer"]

keycloak_admin = KeycloakAdmin(
    server_url=URL,
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

client = keycloak_admin.create_client(
    payload={
        "clientId": "client1",
        "publicClient": False,
        "redirectUris": [issuer],
    },
    skip_exists=True,
)

指定クライアントの Secret を再生成する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env python3
from keycloak import KeycloakAdmin

keycloak_admin = KeycloakAdmin(
    server_url="http://localhost:8080/auth/",
    username="admin",
    password="password",
    realm_name="master",
    verify=True,
)

client_id = keycloak_admin.get_client_id("client1")
data = keycloak_admin.generate_client_secrets(client_id)
print(data["value"])