OpenIDMをちょこっと触ってみました

今年はOSSのIdMがくる!? と期待もこめてOpenIDMを紹介。年末年始に空き時間を使ってちょこっとさわってみました。

IdMとは

IdMについてはOracleの記事が分かり易かったのでこちらを紹介。

OpenIDMは上記の説明でいうとIDライフサイクル管理を担当します。Oracleの製品でいうとOracle Identity Managerの位置に相当するソフトウェアですね。

OpenIDMとは

OpenAMを開発しているForgeRock社によるIdMソフトウェア。OpenAMと同じくこちらもOSSでライセンスはCDDL。

OpenAMは元々SunがOpenSSOとして開発していて、Oracleに買収されたあと元Sunの人たちがForgeRock社を立ち上げてOpenSSOをForkして開発されています。一方、OpenIDMはベースはなくスクラッチで開発されている模様(参考)。ただし、外部リソースとのコネクタ部分はSunがOSSで開発していたIdentity Connector FrameworkをForkしたOpenICFを採用している(OpenICFもForgeRockで開発されている)。

最新安定板はバージョン2.0.3。次バージョン2.1は予定ではXpress版がもうでているはずなのだがまだ出ていない。。。
ロードマップはこちら

動かしてみる

お試しなので最新安定板ではなく、2.1.0 Experimental Nightly 版を使用してみた。

OSSなのに意外?とドキュメントがあり、インストール&サンプルを動かすチュートリアル(OpenIDM 2.1.0 Installation Guide)がしっかり書かれているので、簡単に動かせます。英語だけど、平易な英語で書かれていて分かり易い。

OpenIDM 2.1.0 Installation Guideの目次にサンプル一覧がある。LDAPSQL系は別途環境を用意しないといけないが、それ以外はOpenIDM単体ですぐに試せます。

3.2. Sample 1 - XML File
3.3. Sample 2 - LDAP One Way
3.4. Sample 2b - LDAP Two Way
3.5. Sample 2c - Synchronizing LDAP Group Membership
3.6. Sample 2d - Synchronizing LDAP Groups
3.7. Sample 3 - Scripted SQL
3.8. Sample 4 - CSV File
3.9. Sample 5 - Synchronization of Two Resources
3.10. Sample 6 - LiveSync Between Two LDAP Servers
3.11. Sample 7 - Scripting a SCIM-like Schema
3.12. Sample 8 - Logging in Scripts
3.13. Sample 9 - Asynchronous Reconciliation Using Workflows

さくっと動かしたい人は、Sample 1、Sampl 4、Sample 5がおすすめです。

  • Sample 1 : XMLで書かれたユーザー情報をOpenIDMのRepositoryに同期させるサンプル。プロビジョニング先はなし。
  • Sample 4 : CSVで書かれたユーザー情報をOpenIDMのRepositoryに同期させるサンプル。これもプロビジョニング先はなし。
  • Sample 5 : XMLで書かれたユーザー情報をOpenIDMのRepositoryに同期させつつ、別のXMLファイルにプロビジョニングするサンプル。

Sampleごとにコンフィグファイルが用意されており、起動時にオプションでディレクトリを切り替えればすぐに試せます。例えばSample 1を試したければ、OpenIDMを下記のように実行すればOK。

cd /path/to/openidm
./startup.sh -p samples/sample1

OpenIDMのアーキテクチャ

Integrator's GuideのChapter 1. Architectural Overviewを参照。2010年頃からフルスクラッチで開発されているのでモダンな作りになっている。

気になった特徴は以下。

  • REST API
    • 基本的にRESTでHTTP経由で操作するようになっている。他システムとの連携がやりやすそうです。
  • Script Engineによる柔軟さ
    • OpenIDM自体はJavaで開発されているが、Script Engine(Rhino)が動いておりJavaScriptで色々と定義するようになっている。例えば、ユーザーの姓、名をあるシステムに連携(プロビジョニング)する際は、「姓 名」と連結しないといけない場合など、JavaScriptで以下のように定義できる。
  "target": "displayName",
  "source": "";
  "transform": {
      "type": "text/javascript",
      "source": "(source.lastName +', ' + source.firstName;)"
  }
  • 2種類の同期
    • ReconciliationとLiveSyncの2種類の方法がある。
      • Reconciliationは機能的には差分同期。ソース(同期元)とターゲット(同期先)のデータを比較して変更点を認識して結果を反映。
      • LiveSyncはソースのチェンジログをもとに同期する方法。Reconciliationと異なり差分をチェックする必要がないので軽量。ただし、チェンジログはOpenIDMが認識できる形でないとだめ。現在のバージョンだとOpenDJとActiveDirectoryに対応しているみたい。
    • また、直接OpenIDMのRepository(ManagedUser)をRESTで更新してやれば、即座に他のリソースに反映することも可能です。リアルタイム同期をしたい場合はREST APIをたたく方がいいのかも。

REST APIでユーザー登録・更新

Linuxからならcurlコマンドで簡単にできる。HTTPヘッダでログイン情報を渡す必要がある。ボディでJSON形式でデータを渡してあげる。

  • RESTで登録
curl --header "X-OpenIDM-Username: openidm-admin" --header "X-OpenIDM-Password: openidm-admin" --request PUT --data '{ "email":"fdoe@example.com","familyName":"Doe","userName":"fdoe", "givenName":"Felicitas","displayName":"Felicitas Doe" }' "http://localhost:8080/openidm/managed/user/fdoe"


  • RESTで更新
    • header "If-Match: *" を追加しているのがポイント。
curl --header "If-Match: *" --header "X-OpenIDM-Username: openidm-admin" --header "X-OpenIDM-Password: openidm-admin" --data '{"email":"fdoe@example.com","familyName":"Doe","userName":"fdoe", "givenName":"Felicitas","displayName":"Felicitas Doe"}' --request PUT "http://localhost:8080/openidm/managed/user/fdoe"


  • RESTで更新(特定属性のみ指定)
    • PATCHで特定属性のみ更新することもできる。
curl --header "If-Match: *" --header "X-OpenIDM-Username: X-OpenIDM-Password: openidm-admin" --data '[{"replace":"givenName","value":"Felicitas Changed!"}]' --request PATCH "http://localhost:8080/openidm/managed/user/fdoe"

または

curl --X-OpenIDM-Password: openidm-admin" --data '[{"replace":"givenName","value":"Felicitas Changed!"}]' --request POST "http://localhost:8080/openidm/managed/user/fdoe?_action=patch"

おまけ:性能もちょっとみて見た

MacBook AirでVirtual Boxを動かし、CentOS6.2で確認。メモリ512MB割り当ててます。CPUは1つのみ。

RepositoryはデフォルトのOrientDBからMySQLに変更しています。Chapter 4. Installing a Repository For Productionに変更方法が書かれています。

Reconciliationで差分同期させてかかった時間を確認してみました。

  • CSV->ManagedUser(MySQL)->OpenLDAP
    • 1000件(追加): 135秒
    • 1000件(更新なし): 56秒
    • 1000件(更新1000件): 124秒
  • OpenLDAP->ManagedUser(MySQL)->OpenLDAP
    • 1000件(追加): 104秒
    • 1000件(更新なし): 35秒
    • 1000件(更新1000件): 101秒

topで見るとjavaプロセス(つまりOpenIDM)の処理がボトルネックのようでほとんど使い切っていました。内部的にはマルチスレッドで処理されているようなので、CPUを増やせば速くなるかも??
他の製品を触ったことがないのでこれが遅いのか速いのか何とも言えませんが。。。
個人的な感覚としてはちょっと遅いようにも思う。1000件LDAPインポートだけだと一瞬ですしね。JavaScriptの評価が遅いのかも? RhinoじゃなくてV8あたりにすれば速くなったりしないかな〜