OpenAM

お仕事で使ったけども、非常に苦労させられました。

ちゃんとまとめたかったけども、うまくまとめられなかったので非常に読みにくい感じになってます。気が向いたら直すかもしれません。
また、この記事は愚痴に近いものがあるので、問題解決とかの参考にはなりません。

「ならなぜ書いた!?」というと、自分は本当に死にたくなるほど苦労したので、OpenAMに巻き込まれないようにして欲しい、手を出す時に「OSSだから無料!」とか思わず、本当に運用できるか判断してから導入してもらいたい、という一利用者の声ということで。

そんなわけで、OpenAMに触れつつ、主に不満な点を書きます。
自分が無知で無能でただ勝手に苦労しただけである事を願いたい。


おことわり

  • OpenAMの主要機能の一つと思われる「ポリシー」についてはほとんどわからないです
  • 以降の話で出てくるのはOpenAMが持つSSO(認証)についてのみです

OpenAMとは

  • シングルサインオン(SSO)を提供するソフトウェア
  • SSO方式はいくつかある
    • エージェント方式
      • ApacheJ2EEコンテナ等のサーバへSSOエージェントを埋め込み、OpenAMとエージェント間で連携してSSO認証する
      • クロスドメインSSO(CDSSO)でもOK
    • REST APIを使ったSSO認証も可能(なので独自フィルタを書けばエージェントは不要。Liferayなどのサポートもこれで対応してる。)
    • SAML認証
    • OAuth方式は11ぐらいから使えたはず
    • バースプロキシ方式...は各方式の応用みたいなもの。どうしてもエージェントを入れるのが難しい場合などに使う。
  • 認可の考えがあり、アクセスの制御もできる(教員専用とか、生徒・教員共用とか。)
    • このあたりは「ポリシー」という考えで行えるが、仕事では使わなかったため、あまり詳しくない。かなり柔軟に設定できそうだったぐらい。

歴史

  • 古くはSunがあった頃で、Sun Java System Access Managerというのが前身。
  • それからOpenSSOになりOSS化された。
  • SunがOracleに吸収され、OpenSSOOracle社所有。
  • その後、SunのOpenSSOに関わってた社員(だったかな?)らがfork。forgerock社を設立し、OpenAMとなった。はず。

良い点

  • コードが公開されてる。唯一の良い点。
  • 利用はタダ!・・・という理由で採用すると絶対苦しむのでこれだけで採用し無い事。

悪い点

  • 実運用となるとネットの情報だけでなく、ノウハウがないと難しい。
  • 日本語情報は少ない。少ないってレベルじゃないぐらい少ない。導入してみましたレベルのサイトは参考にしなくて良い
  • コードが辛い
    • 自分が書いたらもっと酷い実装になることを棚に上げて言うけども、決して良いコードではない。
    • 主要機能は2000行を超えるクラスが割りと多くあるし、利用されない変数があったり。でもこれだけ大きいプロダクトになると仕方が無いのかもしれない。
    • エラーレベルのログがあまりアテにならない。運用時でもデバッグ(メッセージ)レベルはほしい。
    • 丁寧にキャッチしてExceptionの情報を使わずに、エラーメッセージを吐いてくれる。例外時どこで発生したかの情報がわからなくなるので、メッセージレベルにしていないと原因がわからなくなる。
    • たまに例外を握りつぶす。

もしOpenAMを採用するなら・・・

まずすべきと思うのは、OpenAMの理解。触って覚えるのがなんだかんだで良い気がする。

  • OpenSSO時代の資料を参照。英語でわかんなくても読む。 => http://docs.oracle.com/cd/E19681-01/
    • エージェント方式の話やクロスドメインSSOについての話など古い機能の話しは網羅できてる。
    • OAuthとかOpenIDとかはサポート外。こちらはOpenAMのドキュメントにちょろっと書いてある。
    • OpenSSOアーキテクチャの理解を深めるために
      • OpenAMではこのあたりのドキュメントが少ない
    • 古いドキュメントなので、当然OpenAMと違う部分もあるが、OpenAMの12系になった今でも通用する部分も多い。(古くからある機能はほとんど変わってないので)

運用面だと

  • 1日何アクセス、何セッション払いだす想定か
  • クッキーの永続化は必要か(セッションクッキーではなく期限付きクッキーで発行する場合は設定変更必要)
    • 10系のデフォルトでは5000セッション、1ユーザあたりのセッション数制限なし。(設定で調整可能)
  • ログは「メッセージ(trace/debugに当たる)」で出す事を個人的には推奨。問題があったときにログからでは原因がわからないため。
  • クロスドメインSSO(OpenAMと異なるFQDN間でのSSO)を行うか否か
  • 認証先としてADを使うか、DB(JDBC)を使うか
    • ADの場合ホットスタンバイ的なPrimary-Secoundary構成が取れるが、このあたりのLDAPConnectionを扱う部分がバグってる。出来れば設定で冗長化せず、LBで冗長化することを勧める。
    • DBはパスワード情報を扱うのでより警戒する。プレーンで扱っていない場合、パスワードを扱うための変換クラスを1個書く必要がある(saltとMD5で変換するなど。)
  • 予想外のアクセスがしばしば発生するのでユーザに見える形になることを許容できるか
  • 自動化に時間を割けるか
    • 管理ツールというものがあり、内蔵データストアが持つ設定情報をサブコマンド形式で書き換えて設定できる。
  • 切り戻し手段を用意しておく。
  • 画面遷移の問題とか、バグか否かわからない動作とか、リダイレクトループとか、予想外の事は絶対に起こるのでそれに対する時間を割けるか

多分他にも色々ありそうだけど、とりあえず。

この辺の調査をするとなると、動作確認とか予想外の事が色々出てきて色々やる事になって、多分予定していた工数じゃ足りなくなる。

個人的には内製をオススメしたい

OpenAMを採用する場合、画面とかあまり気にせず、運用しながら少しずつよくしていこうねーというスタンスが取れる場合ぐらいかと思う。
でも認証はかなりシビアなシステムで、安定して稼動しないと非常に困る。
設定は再起動しないと反映されないものもあるし、ノウハウが無いと実際に運用して予期せぬ出来事ばかりで、問題解決に時間がかかって支障が出る。
なので、実際に投入するには敷居が高くて、導入できない場合が多いはず。

その場合は小さいシステムで試しつつ、徐々に移行していく感じになっているけども、
必ず切り戻し手段は用意しておきたい。
そのまま導入してハッピーになれることはまず無いと思うので、OpenAMを使わず、内製することも視野にいれてほしい。

OpenAM自体は非常に多機能で魅力的なのは間違いなくて、活用できれば短期間でSSOシステムを構築できるのは間違いない。
ただ、一歩外れると、途端にどうすれば良いかわからなくなる。ドキュメントにあるか探して、記述が無ければコード読むなり設定いじって試行錯誤しないといけない。
バグがないわけではないし、リリース後も問題対応・保守していくことを考えると、内製してしまったほうが良いのでは、と思う。
OpenIDとか流行りものの認証技術があるし、SSOの手段はOpenAMに限らず公開された仕様・実装は色々ある。

古い製品だとサポートできないとかコストが高くついて手が出せないといった場合もあるけど、OpenAMなら解決できる!というとそうでもないはず。
確かにレガシーなシステムをサポートできる仕組みとしてプロキシとか代理認証とか色々あるけど、修正なしで対応できる事例は稀だと思う。
(このあたり自信なく表現してるのは、某資料ではめっちゃメリットとして推してて、自分はアプリがOpenAMのために作られたとかでない限り修正なしでの対応は今のところ無理だと思ってる。)

OpenAMで食ってるコンサルの人と話もしたけど、全部は理解できてなくて、大体こういったことができるといった知見でソリューションの提案とかやってる話だった。
自社じゃそんなに時間かけられないから、コンサルタントを立てよう、とするのは良いと思う。
でも相談するにも導入するにもサポートとかで金がかかる。それでちゃんと安く上がるか?というのも疑問。
(おいくら万円かかるかの話は自分は全くわからないので、本当に安く上がるのかもしれないけど、どうなんだろう。)

SSO化しよう!となると何にしても検討する時間は必要になる。

苦労話とか

色々書いたけど、本筋でないものはこちらに持ってきたり。感情的になってるので重複してるとこもあるかも。

悪い例にて・・・

  • 日本語の情報より英語の情報
    • 導入してみたレベルの記事はあまり参考にならない。
      • 古いのもあるけど、理由も無く設定してる部分があったりしてそれを鵜呑みにして問題を引き起こすときがあった。
      • 英語だがOpenAMのインストールガイドを見たほうが良い。
    • 海外はある程度フォーラムとかが活発なので、問題が起きた時にメッセージでググッたら解決策があったりする。ただ事象が微妙に違ったりというのがあったので、やっぱり英語が読めないと辛い。
  • ノウハウがないと難しい、というのは、OpenAMの挙動から、バグまでいろいろ。
    • データストアのLDAP冗長化がバグってる。パッチを書いて対応したが、そもそもnetworkチームの問題だったのでは、という部分もあったり。怖い。
    • xxx.jpといったドメインだと初期設定さえ出来ない謎仕様。このせいでステージング環境では問題なかったけど本番環境でダメだったってのがあった。
    • (CDSSO時のみ)「うちのアプリは複数サーバがあるけど、どれにエージェント入れればいい?LBから後ろに来るサーバには全部入れないとダメ?プロファイルは使いまわしできないの?1エージェント1プロファイル?え、なんで?ログアウト時に問題が出る?は?」
    • Snapshotだと動かないこともしばしば。バージョンを下げてタグ付きを使うか、安定版(バグが無いとは言っていない)を使う。

ログの批判が多いのだけど、ぜひ使ってみてください。デフォルトでは静過ぎて何が起きてるかわからないと思います。

  • 「問題がおきてもエラーレベル・警告レベルで充分だろ、馬鹿な事を・・・」と思うけど、メッセージはなんとなくそれっぽいのが出てきても、なんでそうなったかの原因がわからなくて辛い思いする。
    • 「再現待ち」として良いのか否かの区別もつかない。性能低下とかディスク圧迫などのデメリットがあるけど、要求を満たせるならメッセージで出したほうが良い。
    • ERRORレベルのログが出たとき、本当に何がどうして起きたのかわからない。まじで。
  • 出力が結構多いので追うのが辛いけど、アクセスログやログイン時のログは残るのでそこから時間に一致するログを追う感じ
  • コード見ればわかるけど、警告レベルはあまりなくて、errorかdebugばかり。

予想外のアクセスってなんぞ?→単純に言えば画面遷移です。ただその条件がいろいろあって何をしたら表示されるか把握できない。結果的にユーザに予期しない画面が表示される事がある。

  • 例えば、OpenAMのログアウトURLを踏んだ時の挙動だが、このとき認証されていない状態だとログイン画面に遷移する。
    • ログアウト後に任意の画面へリダイレクトさせるパラメータgotoを指定できるが、この条件だと機能しない。
  • ログイン画面を開きっぱなしにした後に操作を行うとセッションタイムアウトになる
    • この期限がデフォルトでたしか180秒。たまたま導入調査してた時に気づけたけど、この動きを知らず、せっかちなテスターしかいなかったら気づけないだろうなぁ。
    • ちなみに、この期間を延ばしたい場合、どこを修正すれば良いかというと、認証モジュール毎のリソースファイルとOpenAMの設定・・・なんで2箇所・・・。
    • 対策としてはjspを使うので、全部書き換える。ただ、独自のJSPタグ(?)を使っているので、これを理解する必要がある。(大体削っちゃっても動くけども。)

自動化はしたほうがよい

  • 最初は画面ポチポチやってるのが楽しいけど、絶対辛くなる。
    • 洋書のOpenAMの本は設定をする時は管理ツールを使うような手順になってた(はず...)
  • バックアップに使える設定のインポート/エクスポート機能について
    • エクスポート→インポート→エクスポートすると、各エクスポートした段階のファイル(LDIF)の差分が凄い発生する(同じ設定をインポートしたはずじゃ・・・)
      • 自分がやったときは、この差分の影響を調査しきれず、手運用になってます。

環境は潤沢に贅沢に

  • 1サーバに複数いれたりしない。OpenAM複数台とか、エージェント導入先と相乗りとか、やめたほうが良い。
  • 本当に本番に近い環境を作る。FW/LB周りも近づけたい。(独自のコネクションプーリング実装があって、これがキープアライブの設定により問題が起きるときがある。1回これに関連する問題で2週間ぐらい悩まされた後、考えるのを止めた。)
  • リモートデバッグ環境があるとデバッグが超捗る
    • うちはそんな贅沢な環境はなかった。自宅で環境作ってリモートデバッグしてた。サービスサービス。