1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Keycloak admin REST API を叩いて realm と user を新規作成する

Posted at

step1: keycloakをlocalhost:8080で起動する。

環境変数で管理者である"admin"のパスワードを"admin"に設定している

docker run -t --rm -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:21.0.2 start-dev --http-port=8080

step2: 以下のPythonを実行

  1. 最初にアクセストークンを取得
  2. 新しいrealmであるnewrealmを作成
  3. newrealmにuser1,user2,user3を追加、各ユーザーのパスワードとして"password"を設定
from typing import Dict, Optional
from urllib import parse, request, error
import os
import json

baseurl="http://localhost:8080"
email_domain="example.com"

def main():
    code, res = req(
        "/realms/master/protocol/openid-connect/token",
        data_urlencoded={"username":"admin", "password":"admin", "grant_type":"password", "client_id":"admin-cli"}
    )
    token=res["access_token"]
    realm="newrealm"
    add_realm(realm, token)
    for username in ["user1", "user2", "user3"]:
        add_user(username, "password", realm, token)

def add_realm(realm, token):
    return req(
        "/admin/realms",
        data_json={
            "id": realm,
            "realm": realm,
            "displayName": "New Realm",
            "enabled": True,
            "sslRequired": "external",
            "registrationAllowed": False,
            "loginWithEmailAllowed": True,
            "duplicateEmailsAllowed": False,
            "resetPasswordAllowed": False,
            "editUsernameAllowed": False,
            "bruteForceProtected": True
        },
        headers=get_headers(token)
    )
def add_user(username, password, realm, token):
    return req(
        "/admin/realms/{}/users".format(realm),
        data_json={
            "enabled":True,
            "username":username,
            "email":"{}@{}".format(username, email_domain),
            "emailVerified":True,
            "credentials":[{"type":"password","value":password,"temporary":False}]
        },
        headers=get_headers(token)
    )
def get_headers(token):
    return {
        "Content-Type":"application/json",
        "Authorization":"Bearer {}".format(token)
    }
def req(url, data_json:Optional[Dict]=None, data_urlencoded:Optional[Dict]=None, headers:Optional[Dict]=None):
    headers=headers or {}
    data=None
    if data_json:
        data=json.dumps(data_json)
    if data_urlencoded:
        data=parse.urlencode(data_urlencoded)
    url=baseurl+url
    print('{} {} \n--data "{}"'.format(("POST" if data else "GET"), url, data), end=" ")
    req = request.Request(url,data.encode('utf-8'),headers)
    def defer(res):
        code, data=res.getcode(), json.loads(res.read().decode("utf-8") or "{}")
        print(code, data)
        return code, data
    try:
        with request.urlopen(req) as res:
            return defer(res)
    except error.HTTPError as e:
        return defer(e)

if __name__=="__main__":
    main()

実行結果

POST http://localhost:8080/realms/master/protocol/openid-connect/token 
--data "username=admin&password=admin&grant_type=password&client_id=admin-cli" 200 {'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0VE41WkdtSG5RTTBRd1FlQnhKR3JUMXN1dzN1QWdNNDduNUpKZ1FBQi1rIn0.eyJleHAiOjE2OTU
wOTMwNzAsImlhdCI6MTY5NTA5MzAxMCwianRpIjoiY2ZiMjAyNzEtZTQ4Mi00MDVkLWJmZDktMzdhNTYyZTE1YTYxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5MDgwL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiIxZWFkYzQ0OC1lMTQzLTQ1NGItOTM5ZS1iYmQwNjA2OWJlYjEiLCJ0eXAiOiJCZWFyZXI
iLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiMWE4MDI1NzktMGZhYi00OGQ1LThjM2UtMmI1ZjZiODJkYzM2IiwiYWNyIjoiMSIsInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6IjFhODAyNTc5LTBmYWItNDhkNS04YzNlLTJiNWY2YjgyZGMzNiIsImVtYWlsX3ZlcmlmaWVkIjp
mYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4ifQ.eP0VXJ7TRq2uyelLbl50hDQL4kKf_7wzE9L_61qOBq1OUh_9M7LaFiLaV7TO6vS0KVd0oIalz18lSqC0ti0Z9LsFtlXq8SlGDYAtJ0Vcdx-JfDEg52zPzKF1lF8CdwvbGegA3O8vxKur6X6qwPW8bmp6GMGrYRXWiZ01EfkwMdbyY0PQDU2s
kN3KObe0iwPObZV5j05uT19gcsqQ-PyKL9wWUP98ipK8Q90lYlpTLWS5erJ1SUd0qTJWkEOYSJ3U46G6D0LuORzgpb9NKDg7eVgQYT7gdyUWayim4pimVgOx1KjiO2oMCssEmHexuGxJ_li021atgegDAjPiUHSSZQ', 'expires_in': 60, 'refresh_expires_in': 1800, 'refresh_token': 
'eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlZjg0YTkzOS1lODhmLTQ2M2EtOWJmMC1jMzhmM2Y5NzQxYmQifQ.eyJleHAiOjE2OTUwOTQ4MTAsImlhdCI6MTY5NTA5MzAxMCwianRpIjoiMDY0NzI2ZTktNjc5My00YjdkLTk3ZTYtMjU1ZTIzMWRlOWM4IiwiaXNzIjoiaHR0cDov
L2xvY2FsaG9zdDo5MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjkwODAvcmVhbG1zL21hc3RlciIsInN1YiI6IjFlYWRjNDQ4LWUxNDMtNDU0Yi05MzllLWJiZDA2MDY5YmViMSIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoi
MWE4MDI1NzktMGZhYi00OGQ1LThjM2UtMmI1ZjZiODJkYzM2Iiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwic2lkIjoiMWE4MDI1NzktMGZhYi00OGQ1LThjM2UtMmI1ZjZiODJkYzM2In0.KwswB_Adc887l3FN1pBmbYTumm6R1q6ManFjCTTfUis', 'token_type': 'Bearer', 'not-before-policy': 0, 'session_state': '1a802579-0fab-48d5-8c3e-2b5f6b82dc36', 'scope': 'email profile'}
POST http://localhost:8080/admin/realms
--data "{"id": "newrealm", "realm": "newrealm", "displayName": "New Realm", "enabled": true, "sslRequired": "external", "registrationAllowed": false, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, "resetPasswordAllowed": false, "editUsernameAllowed": false, "bruteForceProtected": true}" 201 {}
POST http://localhost:8080/admin/realms/newrealm/users
--data "{"enabled": true, "username": "user1", "email": "user1@example.com", "emailVerified": true, "credentials": [{"type": "password", "value": "password", "temporary": false}]}" 201 {}
POST http://localhost:8080/admin/realms/newrealm/users
--data "{"enabled": true, "username": "user2", "email": "user2@example.com", "emailVerified": true, "credentials": [{"type": "password", "value": "password", "temporary": false}]}" 201 {}
POST http://localhost:8080/admin/realms/newrealm/users
--data "{"enabled": true, "username": "user3", "email": "user3@example.com", "emailVerified": true, "credentials": [{"type": "password", "value": "password", "temporary": false}]}" 201 {}

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?