background
keycloakを長らく user federation の LDAP で運用してきました。LDAP で 2FA をするのもできた のですが、OIDC の利用が推奨されたので user federation をやめて IdP(Identity provider) を使うことにしました。
issues
user federationをやめることにより、以下の問題が発生しました。
- LDAP で import された keycloak users は LDAP に完全に依存している。
- LDAPを消すと、ユーザも消える!
- ユーザにアサインしていたroleが全部消える
- LDAPを消すと、ユーザも消える!
- IdP(Identity Providers) でログインしたユーザは全く新しい新規ユーザとなる
- LDAPに紐づいていたユーザの権限は持たない
- LDAP userが残っている場合は、IdP ユーザは作られず、既存のLDAP userにlinkされる
- この場合は LDAP userの権限が引き継がれるが、LDAPを消すとユーザごと消えるので、linkされたのも意味がなくなる
- LDAPを使うと全ユーザのimportが一瞬でできますが、IdPの場合はユーザリストをとってこれないのでユーザにログインを試行してもらわないとユーザが作成されない。
- ユーザがログインを試す前にroleをアサインしておくことができない
solution
netの海を探しても全く事例が見つからないので、既存ユーザを活かすのは諦めました。
新規ユーザを無理やり作り、既存の権限を同じように付与しました。
Procedure
以下の手順で移行を行います。
- 既存(LDAP) usersの権限を全てメモっておく。
- realm admin, client roles, groups などを全てメモっておく。たくさんありすぎる場合はそれ用のscriptをchatGPTに書いてもらいましょう。
- 移行scriptを用意しておく
- "1." でメモったuser権限を入れておきます
-
import_users.py
-
既存(LDAP)のkeycloak usersを出力する
-
keycloak UI:
-
"3-1." で出力しておいた
users.json
を使って、LDAPに依存しない keycloak usersを一括で作成する。- この時、userに対して IdP userのlinkを強制的に埋め込みます。これをしないと、IdP を使って login しようとしたユーザは「どのkeycloak userにlinkしますか?」と聞かれますが、そもそもkeycloak userにpasswordが設定されていないため、linkする対象として承認されることができず詰みます。
-
- 移行scriptを実行し、LDAPユーザが持っていた権限を付与する
移行scripts
ここに使ったscriptを置いておきました。ほぼchatGPTに書いてもらったので超適当です。何も言わないで作ったらnode.jsとpythonで書かれましたw fileごとにpassword必要だし、全く正規化されてないです。
なお、業務に関連しそうなところは目視で削除してるのでこのrepo自体の動作確認はしてません。悪しからず。
適当すぎるポイントは、userを export → 削除 -> import する必要があるんですが、exportした後の削除はUIから行なってるので、IDEのdebug 機能でここでbreakpointして、UIから削除を実行した後に F9 で再開して import させてました。ひどいw
# ここで一時停止して、LDAPユーザをUIから全て消す
pass
LDAP usersを消す方法
IdP はまりポイント 1
IdPの設定で OIDC から user attributes が取れない問題で死ぬほどはまりました。IdPへのリクエスト scopeがデフォルトで openid
しかないのが原因でした。advancedの中に隠れてます。
IdP はまりポイント 2
新しく作ったkeycloak userに Identity provider links
をつけるのが難しくはまりました。
Users > User details > Identity provider links
には2つの設定項目があります。これは想像ですが、私の環境ではこのようになりました。
-
User ID
は OIDC が返却する user profile のusername
に相当? -
Username
は OIDC が返却する user prorileのemail
に相当
しかし、これは利用している OIDC(IdP) の user profileに大きく依存すると思うので適宜適切な値にしてください。
*IdPのmapperで username を違う attributeにアサインすることができますが、これは user の IdP linkには影響しないようです。
Identity providers > Provider details > mappers
で usernameを email とは違うattributeにしてるけど、userのIdP Link に指定する username は emailだったの図
keycloakの具体的な運用方法はまだまだnetの知見が少ないように思います。少しでも役立つ方がいましたらぜひいいねとストックをお願いします!