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 をインストールします。
| 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 コンテナを起動します。
| docker run \
-d \
-p 8080:8080 \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=password \
--name keycloak \
jboss/keycloak
|
Python3 のインストール
Python3 をインストールしておきます。
| dnf install -y python39
alternatives --set python /usr/bin/python3.9
|
python-keycloak のインストール
venv 環境を作成して python-keycloak をインストールします。
| 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,
)
|
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,
)
|
Realm の設定を更新する (master Realm)
keycloak_admin.py の update_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"])
|