エンタープライズ向けシステムの世界にいるとユーザー管理・認証にLDAPサーバーを使っている場面に直面します。 LDAPサーバーはOSSのOpenLDAPだったり、389 Directory Server (Red Hat)、Tivoli Directory Server (IBM)、あるいはMicrosoft Active Directoryかもしれません。
ユーザー認証というコンテキストであれば、2023年現在だとアプリケーションを新規開発するなら認証プロトコルにOIDCかSAMLを使うでしょう。素のLDAPプロトコルで認証するロジックを書くのは面倒です。OIDC/SAMLであればシングル・サインオン可能です。ただし、ユーザー管理のリポジトリとしてLDAPサーバーを (積極的/消極的どちらかの理由で) 有効活用したいケースがあります。
この記事では認証ソフトウェアのKeycloakを用いて、LDAPサーバーをバックエンドに据えて、LDAPユーザーでOIDC認証を実現する方法を残します。
環境情報
ソフトウェア
この記事ではLDAPサーバーにOpenLDAPを使用します。 OpenLDAPとKeycloakはどちらもDockerコンテナとして起動します。 以下のコンテナイメージを使用します。
コンポーネント名 | コンテナイメージ |
---|---|
OpenLDAP | docker.io/bitnami/openldap:2.6.5 |
Keycloak | quay.io/keycloak/keycloak:22.0.1 |
LDAP
LDAPは次の設定でユーザー情報が投入されているとします。
- ドメインDN:
dc=example,dc=com
- ユーザー組織単位 (OU):
users
- 匿名ユーザーによる操作: NG
- ユーザー: 2つ登録済み
- ID:
hatenademo1
, パスワード:H0ge_Fuga
- ID:
hatenademo2
, パスワード:P1yo-piY0
- ID:
環境セットアップ
コンテナをDocker Composeでまとめて起動します。
compose.yml の作成
まずはDocker Compose定義ファイル compose.yml を作成します。 compose.yml のサンプルを以下に示します。
内容としてはOpenLDAPに管理者ユーザー admin
と、環境情報で定義したLDAP設定、2つのユーザー情報 hatenademo1
hatenademo2
を環境変数で投入しています。
Keycloakは開発モード start-dev
で動かします。
version: "3" services: openldap: container_name: openldap image: docker.io/bitnami/openldap:2.6.5 ports: - "1389:1389" environment: LDAP_ADMIN_USERNAME: admin LDAP_ADMIN_PASSWORD: adminpassword LDAP_USERS: hatenademo1,hatenademo2 LDAP_PASSWORDS: H0ge_Fuga,P1yo-piY0 LDAP_ROOT: dc=example,dc=com LDAP_USER_DC: users # ou=users LDAP_ALLOW_ANON_BINDING: no keycloak: container_name: keycloak image: quay.io/keycloak/keycloak:22.0.1 command: ["start-dev"] ports: - "8080:8080" environment: KEYCLOAK_ADMIN: keycloakadmin KEYCLOAK_ADMIN_PASSWORD: Kc_Admin_Pass KC_HEALTH_ENABLED: true healthcheck: test: ["CMD", "curl", "--head", "-fsS", "http://localhost:8080/health/ready"] interval: 10s timeout: 3s retries: 3 start_period: 30s
コンテナ起動
compose.yml をインプットに、docker compose
コマンドでコンテナを起動します。
$ docker compose up -d [+] Running 3/3 ✔ Network hatenademo_default Created ✔ Container openldap Started ✔ Container keycloak Started
OpenLDAPサーバーに ldapsearch
コマンドを発行すると、2つのユーザーが登録されています。
$ ldapsearch -x -H "ldap://localhost:1389" -D "cn=admin,dc=example,dc=com" -W -b "ou=users,dc=example,dc=com" "objectClass=inetOrgPerson" Enter LDAP Password: (adminユーザーのパスワード) (...中略...) # hatenademo1, users, example.com dn: cn=hatenademo1,ou=users,dc=example,dc=com cn: User1 cn: hatenademo1 sn: Bar1 objectClass: inetOrgPerson uid: hatenademo1 (...その他の属性は省略...) # hatenademo2, users, example.com dn: cn=hatenademo2,ou=users,dc=example,dc=com cn: User2 cn: hatenademo2 sn: Bar2 objectClass: inetOrgPerson uid: hatenademo2 (...その他の属性は省略...)
Keycloak ユーザーフェデレーション設定
ここから本題です。KeycloakがLDAPサーバーをバックエンドのユーザーリポジトリとして扱う設定は、Keycloakの「ユーザーフェデレーション」という機能で扱います。フェデレーション設定をKeycloakのレルム ldap-demo
に入れると仮定して後続に設定を進めます。
LDAPプロバイダーの設定
コンテナで立てたKeycloakの管理コンソールに http://localhost:8080
でアクセスし、Keycloak管理者ユーザーでログインします。
レルムが未作成の場合はログイン後にレルム ldap-demo
を作成してください。
レルム選択後に左メニュー最下部に「User federation」メニューがあるので選択します。 フェデレーション設定するプロバイダーの選択画面が表示されるので「Add Ldap provider」を選択して設定入力画面に遷移します。
LDAP接続情報の設定
フェデレーション設定画面でLDAPサーバーの種類と接続情報を入力します。
General options > Vender (LDAPサーバーの種類) は Other
を選択してください。
プルダウンにはADやTivoliといった選択肢が表示されますが、OpenLDAPの場合はOtherでよいです。
また、Connection and authentication settings (接続情報) は必須属性を埋めます。必須属性以外はデフォルト値のままでOKです。
接続情報の入力例を次の表と図で示します。今回はコンテナで構築しているので、LDAP URLはKeycloakコンテナから見たOpenLDAPのホスト名・ポート番号を指定してください。ホスト名に localhost
を指定しても接続できないことに注意です。
設定名 | 設定値 |
---|---|
Connection URL | ldap://openldap:1389 |
Bind type | simple |
Bind DN | cn=admin,dc=example,dc=com |
Bind credential | adminpassword |
設定を埋めたら「Test connection」と「Test authentication」ボタンで疎通疎通確認します。 それぞれテストOKのポップアップが表示されたら疎通確認は完了です。
LDAPユーザー検索条件の設定
Keycloakが認証操作を実行するときにLDAPサーバーを検索する条件を設定します。
LDAP serching and updating の必須属性を埋めて保存します。入力例を次の表と図で示します。
今回はKeycloakからLDAPサーバーに属性変更操作を想定していないので、READ_ONLY
を指定してください。
設定名 | 設定値 |
---|---|
Edit mode | READ_ONLY |
Users DN | ou=users,dc=example,dc=com |
Username LDAP attribute | uid |
RDN LDAP attribute | uid |
UUID LDAP attribute | uid |
User object classes | inetOrgPerson, organizationalPerson |
設定を全て埋めたら「Save」ボタンで設定を保存すれば完了です。
疎通確認
実際にLDAPユーザーで認証できるのか試します。 認証するOIDCクライアントアプリケーションとして、Keycloakが標準で用意しているアカウントコンソールを使用します。
アカウントコンソールのURL http://localhost:8080/realms/ldap-demo/account/
にアクセスしてアカウントコンソールを開きます。
Sign in ボタンを押下するとログインフォームが表示されるので、LDAPサーバーに登録済みのユーザーIDとパスワードを指定してログインできます。
ログインに成功すると、アカウントコンソール右上にはLDAPサーバーに登録してあるユーザーの姓名が表示されています。
参考資料
- Keycloak Server Administration Guide - Using external storage
- 実践Keycloak - OpenID Connect、OAuth 2.0を利用したモダンアプリケーションのセキュリティー保護 (オライリー・ジャパン)
以上。