midPoint のオブジェクトテンプレートを活用する

[midPoint by OpenStandia Advent Calendar 2024](https://qiita.com/advent-calendar/2024/midpoint-by-openstandia) の14日目は、midPoint のオブジェクトテンプレート機能について紹介します。オブジェクトテンプレートは、[13日目の記事](https://qiita.com/wadahiro/items/fdff99cd782c1d0b1557)で解説したアーキタイプとも関連します。

:::note info
13日目までで構築した環境が前提となります。
:::

# オブジェクトテンプレートとは

オブジェクトテンプレートとは、midPointで管理されるオブジェクト（ユーザー、組織、ロールなど）に対して適用されるテンプレート機能です。例えば、ユーザーオブジェクトが持つ「姓（familyName）」、「名（givenName）」属性より値を計算して「表示名（fullName）」属性に設定するといった、あるオブジェクト内における値のマッピングや生成を行うことができます。他にも、ロールの自動アサイン、スキーマのカスタマイズ、フォームバリデーションの設定機能も備えます。

公式ドキュメントでの説明は下記にあります。

https://docs.evolveum.com/midpoint/reference/support-4.8/expressions/object-template/

また、The Book内でも解説があります。

https://docs.evolveum.com/book/practical-identity-management-with-midpoint.html#_object_templates

# アーキタイプとの関連

オブジェクトテンプレートを作成しただけでは、その効果は適用されません。どのオブジェクトタイプに適用するかmidPointに指示する必要があります。ここで登場するのが、[13日目の記事]()で解説したアーキタイプです。**アーキタイプの設定において、どのオブジェクトテンプレートを適用するか設定可能**になっています。アーキタイプ別に適用するルールを切り替えることができるのは、非常に便利です（例：正社員の場合は表示名には電話番号を含めるが、ビジネスパートナーの場合は表示名に所属会社名を含めるなど）。

:::note info
オブジェクトテンプレートはシステム設定（SystemConfiguration設定）にて、グローバルに適用することもできます。midPointにアーキタイプが導入される前は、グローバル設定で適用していましたが、アーキタイプ導入後は、各アーキタイプに適用するオブジェクトテンプレートを設定する方法を基本的には使用します。

ただし、依然とグローバル設定で利用するケースもあります。例えば、オブジェクトテンプレートのスキーマのカスタマイズ機能を使って、UIの表示項目や表示名を変更する場合です。アーキタイプに紐づく画面表示では、アーキタイプに紐づけたオブジェクトテンプレートを利用しますが、どのアーキタイプにも紐づかないオブジェクトの画面表示では、グローバル設定のオブジェクトテンプレートが利用されます。

また、その他にオブジェクトテンプレートを個別適用可能な箇所もあります。[5日目の記事などで登場したリソース設定での「同期の設定」](https://qiita.com/wadahiro/items/a239a743af5404a7325f#%E5%90%8C%E6%9C%9F%E3%81%AE%E8%A8%AD%E5%AE%9A)です。「状況（Situation）」に応じてアクションを設定していましたが、このアクションの詳細設定で、オブジェクトテンプレートの設定が可能になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/b883c9a7-d0f5-3369-10a2-f9d126aa928c.png)
:::

# オブジェクトテンプレートの機能を試す

[13日目の記事](https://qiita.com/wadahiro/items/fdff99cd782c1d0b1557)で作成したアーキタイプに対して、専用のオブジェクトテンプレートを作成し、各種機能を試してみます。

## オブジェクトテンプレートの作成

画面左メニューの「オブジェクト・テンプレート ＞ 新規オブジェクト・テンプレート」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/2d79e09c-e889-a028-5771-b78357251086.png)

新規オブジェクト・テンプレートの作成画面が表示されます。以下を設定し、一旦「保存」ボタンをクリックして保存します。

- **名前**：`Employee Object Template`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/c6f94238-5b5a-cd4b-c05c-c7e65cda01f1.png)




## アーキタイプにオブジェクトテンプレートを設定

画面左メニューの「アーキタイプ ＞ すべてのアーキタイプ」をクリックしてアーキタイプ一覧を表示し、「Employee」アーキタイプをクリックして詳細画面を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/0b3bef61-a82b-bdee-e557-3431f01c4049.png)


詳細画面では、「アーキタイプ・ポリシー」メニューを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/8bd1fa15-c71b-8569-2cbc-c084e786b997.png)

「▶ アーキタイプ・ポリシー」の箇所をクリックして展開し、さらに「空項目を表示する」をクリックして入力項目を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/b6b59fa7-5342-f337-1c72-16461d5c742a.png)

そうすると関連付けるオブジェクト・テンプレートの設定箇所として、「オブジェクト・テンプレート参照」が表示されます。「編集」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/f9a1e221-ca0b-54f3-1c5c-daa64252f486.png)

オブジェクトの選択ダイアログが表示されます。先程作成したオブジェクトテンプレート`Employee Object Template`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/d27db876-593c-c311-9034-9e8f01fd8e0e.png)

設定された状態になります（まだ保存されていません）。「保存」ボタンをクリックして、アーキタイプを保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/65cf64e6-973d-5e31-dd8c-218a39270ba9.png)

これでこのアーキタイプに属するオブジェクトに対して、適用されるオブジェクトテンプレートが設定されました。


## マッピング

例として、姓と名より氏名（`fullName`属性）を生成するようにマッピングをオブジェクトテンプレートに設定してみます。

### マッピングの設定

画面左メニューの「オブジェクト・テンプレート ＞ すべてのオブジェクト・テンプレート」をクリックし、オブジェクトテンプレートの一覧を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/4efbd612-43b1-2ee2-59c9-2fd7d041e105.png)

先ほど作成した`Employee Object Template`をクリックして、その詳細画面を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/45189f38-b73f-2992-bd26-570bab914965.png)

「マッピング」メニューをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/324529f4-1241-b182-c37e-777c111a09cb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/ff951ab1-c07f-3112-1440-202f5349f550.png)をクリックし、マッピング定義の画面を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/dc1e8798-af3e-e856-a596-b8fc023ff050.png)

まずは以下を設定します。

- **名前**：`fullName`
- **強さ**：`強い`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/9033fa5e-aee4-2dd9-7bd8-419e6a9b24c6.png)

次に「ソース」を設定します。デフォルトで「フォーカス」となっているセレクトボックスを`ユーザー`に変更します。その後すぐ下の入力フィールドをクリックするとユーザーオブジェクトの属性をサジェストしてくれます。ここで`familyName`を選択または入力します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/7622f9fb-0623-a609-4218-d5b1cd22e5ef.png)

また、複数ソースを設定したいので、「ソース」の右隣にある![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/ea36b289-03e8-3569-bfc5-2cdb9209b27a.png)をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/bdbe20a8-3172-f95b-24b2-4d117beb49aa.png)

すると追加の入力フィールドが追加されるので、同様の操作を行い`givenName`もソースに設定します。最終的に以下の状態にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/f72c8a3f-16e1-fad3-5717-c92a7d77be21.png)

次に、ターゲットです。ソースと同様の操作で`fullName`を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/0cf1bceb-2001-1f49-5c39-de3240b50493.png)

最後に「式」では、`スクリプト`を選択し、「スクリプトを表示」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/877d704b-a0a9-d743-0a13-5dafc42c9f2e.png)


スクリプトの入力エリアが追加されますので、「コード」に`familyName + " " + givenName`を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/003357ad-1dad-c396-a7a3-4d7e30c5113a.png)


最下部にある「実行」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/9a9d6467-f1c9-0e86-7c6d-88a9dfaa61b7.png)

そうすると元の詳細画面に戻り、設定したマッピングが追加予定で表示されています（緑色の箇所）。「保存」ボタンをクリックして保存します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/981c450a-01d1-5ad6-82c4-afcd61e6b9b4.png)

### マッピングの動作確認

設定した**氏名を生成するマッピング**の動作確認をしてみます。適当なユーザーの詳細画面を表示します。画面上部にある「オプション」をクリックしてメニューを開き、「リコンサイル」にチェックを入れます。この状態で、「変更のプレビュー」をクリックします。

:::note info
「リコンサイル」オプションを設定してオブジェクトを更新すると、何も変更情報がなくても、該当オブジェクトにリンクされているリソースのインバウンド/アウトバンドマッピングや、適用されているオブジェクトテンプレートなどを再計算しなおします。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/2b1eb6b5-a278-20e6-1c24-de5ea8036ce8.png)

すると、オブジェクトテンプレートが評価されて、氏名を生成する変更を予定していることを確認できます。「保存」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/bec87afe-8f4e-bbd6-5e77-971dcdd156e9.png)

ユーザー一覧画面に戻りますが、ちょうどデフォルトでこの一覧画面では「氏名」列がありますので、そこでオブジェクトテンプレートにより設定された値を見ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/bc11c8f2-9537-4547-c1ed-ee812439a5e2.png)

では、残りのユーザーにも適用して更新します。まとめて実施したい場合、一覧画面より複数人選択して「リコンサイル」アクションを実行というオペレーションも可能ですが、既に`HR users import`タスクという取り込みタスクを作成済みのため、今回はこちらを利用します。`HR users import`タスクを開き、「今すぐ実行」ボタンをクリックして再実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/81c2a51d-415f-4b86-4320-df6c8c779464.png)

源泉データ（`./hr/users.csv`）に変更はありませんが、設定したオブジェクトテンプレートが評価されて、差分があるとそれを検知して更新してくれます。タスクが終了すると、以下のように残りのユーザーにもマッピングが適用されたことが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/dba03816-0e78-7687-56a6-98c19810cf1b.png)

もし仮に、源泉データ側で変更（例：改姓）が行われた場合は、`HR users import`タスクの実行で取り込みを再度行うと、連動して「氏名」も自動的に変更されます。

## スキーマのカスタマイズ

オブジェクトテンプレートにより、適用されているオブジェクトのスキーマ情報をカスタマイズすることが可能です。例えば、表示名やヘルプ文言、アクセスコントロールなどをデフォルト設定から上書きすることができます。

例として、`fullName`属性はデフォルトでは「氏名」と訳されて表示されていますが、これをカスタマイズして「表示名」に変更してみます。

### アイテムの設定

`Employee Object Template`の詳細画面を開き、「アイテム」メニューをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/7474d3fd-825a-540b-f516-6077d0f64c47.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/601d976c-33dc-9177-94c5-6a233f96c3a7.png)をクリックしてアイテムの追加画面を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/5c9dc574-d39b-19ce-4fbf-639a1bea9243.png)

「参照」には、マッピングの「ソース」と同様の方法でカスタマイズしたいスキーマ属性を選択します。今回は、`fullName`を選択します。加えて、「ヘルプ」に`このユーザーの表示名です。`と設定しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/c2663693-dd01-f761-89d9-5764f85e57ec.png)

これで「保存」ボタンをクリックして保存します。

### スキーマのカスタマイズの確認

源泉システムより取り込んだ適当なユーザーの詳細画面を開きます。すると、今まで「氏名」と表示されていた項目が「表示名」に変わっていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/0b42e0cf-9287-595a-f751-5834292e2b71.png)

また、「表示名」の右隣の![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/db61ce82-7d28-a997-373f-c44eb29574d4.png)をマウスオーバーさせると、カスタマイズしたヘルプ情報を参照できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/dfb2ef6f-9e13-b0a6-1b9d-538e4959f9f0.png)

この設定はオブジェクトテンプレートが適用されるオブジェクトに限定されているため、他の種類のユーザーには適用されていません。例えば、`administrator`ユーザーの詳細画面を開くと、デフォルトの「氏名」のままであることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/f1bf5a20-3121-88d3-863c-5cefb6f8a530.png)

このように、アーキタイプごとに異なる表示名を設定することで、不必要にカスタム属性[^1]を増やさずとも対応できるようになります。例えば、同じ`fullName`という属性を使いながら、「正社員」アーキタイプのユーザー詳細画面では「氏名」とし、「派遣社員」アーキタイプのユーザー詳細画面では「氏名 / 会社名」と項目表示することが可能です。

[^1]:midPointでは用意されているあらゆるオブジェクトタイプに対して、任意のカスタム属性を追加することが可能です。これについては、別の日に紹介したいと思います。

:::note info
ユーザー詳細画面だけでなく、ユーザー一覧画面もカスタマイズすることができます。今回は割愛しますが、アーキタイプ別に一覧を表示するメニューを追加することが可能です。midPointにはデフォルトで「Person」アーキタイプが存在しますが、そのユーザー一覧を表示するメニューもデフォルトで追加されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35233/8de84136-0aa3-c0c7-a974-b5d4a87e107a.png)

「ユーザー ＞ Persons」をクリックすると「Person」アーキタイプが適用されているユーザーに絞って一覧表示されます。
:::


# まとめ

14日目では、オブジェクトテンプレートについて解説しました。オブジェクトテンプレートを活用することで、アーキタイプごとに個別のカスタマイズ処理が色々実現できることをご理解頂けたかと思います。是非要件に合わせて使っていただければと思います。

今回は割愛しましたが、Groovyスクリプトの記述によるフォームバリデーションの設定も可能です。画面からユーザーなどを登録する要件がある場合、入力値チェック要件が必須になることが多いので非常に役立ちます。

次回は新たなプロビジョニング先として、Active Directory（AD)を追加してみたいと思います。CSV（Addressbook）では連携データはユーザーだけでしたが、ADはグループとそのメンバーのプロビジョニングも可能であり、いわゆるエンタイトルメント管理がmidPointを通じて可能となります。少し高度な設定が必要になりますが、お楽しみに！