KeycloakでActive Directoryのユーザーパスワードを変更する

だいぶ前にZarafaを運用しはじめた頃、ユーザーのパスワードをブラウザから変更できないと気づき、でもそれっぽいプログラムを書いて「安全に運用」する自信もなく、そのままにしていた。家族と親戚には、途方もなく長く、恐らく暗記することは不可能なパスワードを使ってもらっている。

気が付けばZarafaはKopanoに変わり、うちの運用もSamba ad dcを利用したユーザー管理に移行していたが、このパスワード運用方針を変えていない。Microsoftがパスワードの定期変更に対して「古びた時代遅れの極めて価値の低い対策」と断言するずっと前から、新しい対策を「技術力が足りない」が故に実施していたのだった。





このところのSSOへの取り組みでKeycloakに出会い、ユーザーが自分で自分の情報やパスワードを安全に変更できそうな気がしてきた。
ドメインに参加していないデバイスからでもOKだから都合がいい。

やること。

 

環境

Keycloakは最終的にはSamba ad dcサーバーに同居させようと思っているが、現在はお試し環境で稼働している。
既にKerberos認証でSSOできるところまでを実装済み。

ホスト名用途備考
temp.hogeserver.hogeddns.jpKeycloak 10.0.2(Docker版)
8443ポートでサービスを提供。
お試し環境。KeycloakはApacheでProxyしてアクセスしている。
addc.hogeserver.hogeddns.jpSamba ad dcを運用中。Kerberos認証、LDAP(S)サービスを提供。Realm
HOGESERVER.HOGEDDNS.JP

考え方

[Samba ad dc] <-> [Keycloak] はLDAP(S)で情報のやりとりができる。
Keycloakはユーザーの情報をSamba ad dcから持ってきて「自分でため込む」ことができる。
=ユーザーのインポート

しかし、今回はKeycloakでユーザー情報をため込むことはしない。
直接Samba ad dcのユーザー情報をLDAP(S)で書き換える。

このあたり、運営するサーバーの考え方によると思うが、うちはSamba ad dcがバックエンドにいるので、ユーザーの情報を自分でため込む必要はないと考えた。
独自にユーザーを管理するとか、コピーであることに価値があるような運用にはなっていないので。

注意事項

間違ってユーザーを削除してしまうミスに注意。

Keycloakのユーザーフェデレーションで
 編集モードをWRITABLE
に設定し、インポートされたユーザーをKeylcoakから削除…とやると、ユーザーが削除される。

今回の作業では、ユーザー情報を変える=編集モードをWRITABLEにする、ということなので危険を伴う。
お試しをはじめるにあたっては、不測の事態に備えてESXiでスナップショットをとったり、Sambaのバックアップを取ったりしておくのがいいと思う。

※実際にやっちまって痛い目を見ました…。ホントに注意しましょう。

現在の設定と動作の結果

フォームを変更せずにどこまでできるのか試してみる。
今回、2要素認証は対象外。

テストユーザーの作成

操作ミスによってユーザーが削除される可能性も考慮すれば、テスト用のユーザーを作っておくべき。

Samba ad dcでは以下でユーザーを生成できる。Samba ad dcサーバーで…

■ユーザーの生成
$ sudo samba-tool user create hogeuser
New Password:[ユーザーのパスワードを入力]
Retype Password:[ユーザーのパスワードを入力]
User 'hogeuser' created successfully

■グループへの追加
$ sudo samba-tool group addmembers Administrators hogeuser
Added members to group Administrators

■ユーザーの属性変更
$ sudo samba-tool user edit hogeuser
→これでviが起動し、属性を編集できる。最終行に空行を1行入れて、保存終了すれば属性編集完了。

テストユーザーなら消えてもいいし、おかしな状態になっても被害が小さい。

ユーザー情報の編集

更新されないパターン1

ユーザーフェデレーションで編集モードがREAD_ONLYになっていたため、情報の更新ができなかった。

統合Windows認証設定をすることを目的として、ユーザーフェデレーションを追加済み。

項目設定値備考
IDldap
有効オン
ユーザーのインポートオフ
編集モードREAD_ONLYデフォルトのまま
登録の同期オフ

クライアントID「account」のところにあるベースURLにアクセスしてみる。
ドメイン参加しているPCからなら、すぐに管理画面が表示される。

Keycloakにログインしてログを表示させつつ…

■ログレベルをDEBUGにする(デフォルトはINFO)
$ sudo docker exec -u 0 -it keycloak /bin/bash --login
[root@41bf393541e4 /]# /opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=logging/console-handler=CONSOLE:change-log-level(level=DEBUG)'
[root@41bf393541e4 /]# /opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=logging/root-logger=ROOT:change-root-log-level(level=DEBUG)'
[root@41bf393541e4 /]# logout

■ログを表示させる
$ sudo docker logs -f --tail 10 keycloak

※DockerのKeycloakを使っているので、これを使っている。

基本項目っぽい値を入力して保存してみると、当然エラー(You can’t update your account as it is read-only)が発生する。
ログは出力されていない。

更新されないパターン2

マッパーで対応する項目がRead Onlyになっていたため、画面上は成功となるが、ユーザー情報は更新されなかった。

ユーザーフェデレーションで、編集モードをWRITABLEに変更してみる。

項目設定値備考
IDldap
有効オン
ユーザーのインポートオフ
編集モードWRITABLEここを変更
登録の同期オフ

保存すると、Last nameの値が消えてしまった。

そして、一度、タブを閉じてページにアクセスし直したところ、入力した情報は保存されていなかった
samba-toolでユーザー情報を見たけれども、何も更新されていない。

07:37:07,979 DEBUG [org.keycloak.events] (default task-45) type=UPDATE_EMAIL, realmId=discourse, clientId=account, userId=f:141eefc7-3ac2-488c-8d78-f16c4a963943:hogeuser, ipAddress=172.16.nnn.nnn, updated_email=hogeuser@hogeserver.hogeddns.jp

ログも出力されないので、原因がつかみにくかった。

更新できたパターン

編集モードをWRITABLEにしたのに、なんで値が更新されないのか…

項目設定値備考
IDldap
有効オン
ユーザーのインポートオフ
編集モードWRITABLELDAPに書き込めるようにしてある
登録の同期オフ

もしかしてマッパー?ということで、ユーザーフェデレーションのマッパータブを開き、email、first name、last nameの中身を確認してみたら、Read Onlyがオンになっていた。
これらの項目のRead Onlyをオフにしてみたら、値が更新された。

パスワードの変更

パスワードの変更を試してみる。

現在のパスワードと、新しいパスワードx2を入力し、保存ボタンをクリックする。

問題なく更新できた。

フォームのカスタマイズ

アカウント情報をもう少し編集できるようにしたり、表示だけしてマスクしたりしたい。
また、今回はAuthenticatorを表示させないようにもしたい。

こちらでフォームをカスタマイズする実例を示してくれている。
Qiita / Keycloakの管理コンソールの機能をみてみる(利用者編)、ユーザー・アカウント・サービス

各種フォームはテーマとしてまとめて定義するらしい。
新しいテーマを作りたければ、keycloakのテーマをコピーして変更を加えていけば良いとのこと。
Qiita / Keycloakのカスタマイズポイントを整理してみる

Dockerイメージの中を見てみると
/opt/jboss/keycloak/themes
にbaseとkeycloakという2つのテーマが入っている。テーマを何も選択していない状態では、keycloakが使われるようだ。

カスタムテーマを作成

ビルトインされたkeycloakテーマを基にしたカスタムテーマを作って、色々手を入れてみようと思う。
このkeycloakというテーマ、baseというテーマに色々と装飾をしているだけ、の模様。

$ sudo docker exec -u 0 -it keycloak /bin/bash --login
[root@41bf393541e4 account]# cd /opt/jboss/keycloak/themes
[root@41bf393541e4 account]# cp -ar keycloak origin
[root@41bf393541e4 account]# logout

keycloakをコピーしてoriginというテーマができた。

作成したテーマは「レルムの設定」-「テーマ」で選択できる。

Dcokerの中にviがないので、ベースとなる base と origin をまるごとホストに持ってきて編集する。

$ sudo docker cp keycloak:/opt/jboss/keycloak/themes/base ./
$ sudo docker cp keycloak:/opt/jboss/keycloak/themes/origin ./

 

Edit Accountページのカスタマイズ

入力不可にする

eMail, First name, Last nameはユーザーを作ったときに管理サイドで埋める前提で、ユーザーには編集させない…としたい場合、これらの要素を読み取り専用にする。

$ sudo cp base/account/account.ftl origin/account

account.ftl
…
    <div class="col-sm-10 col-md-10">
        <input type="text" class="form-control" id="email" name="email" autofocus readonly value="${(account.email!'')}"/>
    </div>
…
    <div class="col-sm-10 col-md-10">
        <input type="text" class="form-control" id="firstName" name="firstName" readonly value="${(account.firstName!'')}"/>
    </div>
…
    <div class="col-sm-10 col-md-10">
        <input type="text" class="form-control" id="lastName" name="lastName" readonly value="${(account.lastName!'')}"/>
    </div>
…

※赤文字部分を追加。

最初はdisabledとしたけれど、フォーム送信時に値が送られない。そのため、readonlyに変更した。
GRAYCODE / HTML & CSS / 入力できないフォームを設定する

ファイルをDockerの中に送り込んで再起動すれば、設定が反映される。

$ sudo docker cp origin/account/account.ftl keycloak:/opt/jboss/keycloak/themes/origin/account
$ sudo docker restart keycloak

 

編集項目を追加する

ユーザーに編集してもらいたい項目があるかもしれない。

この場合、ユーザーフェデレーションでマッパーを追加し、それをフォームに追加する。
今回は事業所を追加してみた。

項目設定値備考
名前physicalDeliveryOfficeName
マッパータイプuser-attribute-ldap-mapper
User Model AttributphysicalDeliveryOfficeName
LDAP AttributephysicalDeliveryOfficeName
Read Onlyオフ
Is Mandatory In LDAPオフ
Is Binary Attributeオフ

編集フォームに項目を追加する。

account.ftl
        <div class="form-group">
           <div class="col-sm-2 col-md-2">
               <label for="user.attributes.tel" class="control-label">事業所</label>
           </div>

           <div class="col-sm-10 col-md-10">
               <input type="text" class="form-control" id="user.attributes.physicalDeliveryOfficeName" name="user.attributes.physicalDeliveryOfficeName" value="${(account.attributes.physicalDeliveryOfficeName!'')}"/>
           </div>
        </div>

        <div class="form-group">
            <div id="kc-form-buttons" class="col-md-offset-2 col-md-10 submit">
…

ファイルをDockerの中に送り込んで再起動すれば、設定が反映される。

$ sudo docker cp origin/account/account.ftl keycloak:/opt/jboss/keycloak/themes/origin/account
$ sudo docker restart keycloak

 

試してみる

2つの変更をしたフォームで、事業所を編集してみる。

必須項目の3つは readonly のため編集はできず、追加した項目は編集・更新が可能になっている。
狙い通りとなった。

ワンタイムパスワードのページを無効化(未解決っぽい)

どうも totp というオブジェクトを無効化すればメニューからも消えるようだし、設定ページの要素もなくなるようなんだけれど、どうにもやり方が分からない。

仕方がないので、ページの中身をいじってみる。

$ sudo cp base/account/totp.ftl origin/account/totp.ftl

totp.ftl
<#--
    <#if totp.enabled>
        <table class="table table-bordered table-striped">
…
    </form>
    </#if>
    -->

</@layout.mainLayout>

※totp.enabledは必ずtrueになる模様。それをまるごとコメント化してしまった。

編集したファイルをゲストに送り込んで再起動。

$ sudo docker cp origin/account/totp.ftl keycloak:/opt/jboss/keycloak/themes/origin/account
$ sudo docker restart keycloak

ワンタイムパスワードの関する情報が表示されなくなった。
「現在サポートされていません」くらいの表示をしても良かったかもしれないけれども、まずはこれで。

さいごに

正直なところ、思ったよりも時間が掛かった。
もっと簡単に色々とできるのかと思ったけれども、要素を無効化する変更が難しかった。
一方で要素を追加することはサクサクできた、いい感じ。

これでもまだKeycloakが持つ機能のほんの一部しか使えていない。
そもそも、デフォルトで入っているクライアントの中身とか全然分からないし。

やっと勘が掴めてきた…といったところなのかもしれない。

お気軽にどうぞ ~ 投稿に関するご意見・感想・他

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です