=kthrtty/(+blog)

最近旅してないフルスタックサラリーマンジャーマネの旅行の記録

OpenID Unsolicited Positive Assertion

id:ZIGOROuさんに以前ふってもらっていた?Unsolicited Positive Assertionの話をまとめてみる。

半年前のネタ且つ、技術的なインプットが少ないので、既に枯れた感じがするかもしれませんが。。。

Unsolicited Positive Assertionとは

OepnID Authentication 2.0 Finalを検索してください。
OPから一方的にPositive Assertionを発行して、RPにブラウザリダイレクトで投げつけるAssertionですよ、と。要するに、RPからの要求不要(RP initiateではない)な、OPからの応答(OP initiate)と言えば良いでしょうか。

何に使えそう?

  • EIP的なログインポータル構築。

OPで利用してるRPを事前登録しておけば、クリック一つで「エイヤッ」とログイン出来る。Bookmarkletと組み合わせると更に便利になるかも。後述するSLOでも使えるかもね。

  • Single Log Out機能。Libertyでも定義されているSLO。

しかしhirokiさんに寄ると、「微妙」である感は否めないとのこと(そうなのですか?)。間違っていたらフォローして頂きたいw

IdP initiateなSLO
IdPに登録しておいたSPに対して一気にLogout用のAssertionを投げつけ、SPからのレスポンスを待つもの。IdPに登録してある全てのSPに投げるのはダサいので、セッションが有効な間での認証成功Assertionの投げ先SPを記録しても良い。でも、セッションが切れると投げ先SPの情報が揮発するので切ないらしい。
SP initiateなSLO
SPからLogout用のAssertionをIdPに投げつけると、IdP initiateと同じ手続きを開始する。
SLOは分かった。OpenIDのUnsolicited Positive Assertionを使って何するものぞ

まず、考え方。

Assertionとは
認証結果がOKということを返すものだけにあらず。SAMLでは元々広い解釈で作られているけど、OpenIDでは認証結果だけを返す(以上終了、思考停止)ものと取られがちです。でも、あくまでユーザーが本人であることを確認(狭義の認証)したAssertionに、「ログイン」という暗黙のアクティビティが含まれているだけ。

なので、別にAssertionにログアウトしてよ〜というアクティビティが含まれていても良い、というのはとても自然なことかなーと。

つまり、RPは特定ユーザに関するログアウトのAssertionを受け取ったら、それに従いユーザセッションを破棄すれば良いと。

実現方法は?
  1. 仕様をまったく変更しない場合は、Negative Assertionを返して、RPはユーザセッションを無条件に消し去ることで実現。ただし、ブラウザ-RP間のセッションに基づいてユーザを特定するので、Indirect Communicatioが必須なはず。複数のRPに対して非同期に同じことを実施するには、、、iframeやらAjaxやらで解決できるかもしれないけど、クロスドメインAjaxやら3rd Party Cookieの問題が出てくるかもしれません(知識不足は開発者じゃない僕の限界ですw)。
  2. 仕様を変更できる場合は、Auth resのopenid.modeとしてlogoutを指定出来るようにするとか。こういったことが出来ればIndirect Communication不要で非同期に処理できるかもしれない。理由は後述。
  3. 今さっきふと思いついたパターンは、RPがSingle Log Out用のRP Endpointを用意して、そっちにPositive Assertionを投げてもらう方法。RPがどの様にリクエストするかが問題。
非同期に実現するには?

仕様では、Positive AssertionあIndirect communicationとなっているけれども、セッションを壊すようなアクティビティを要求する場合は、OPがUAのフリして直接メッセージを送っても、RPからすればどうでもよいように見える。実現方法の一つ目の場合はできないと思いますが。。。

問題は?
  • Assertionの戻り先は、本来RPから毎回広告されるものなので、return_toをリクエスト毎に柔軟に変更するRPの場合は上手く適用できないかも。RP Discoveryと組み合わせてSLO Endpointを広告するとかは大いにあり得るパターン。その場合はRealmは安直に変えちゃダメですね−。
  • RPからどうやってリクエストするかも問題かな−。ログアウトボタンを押して、どう動くか。色んな方法が考えられるけど、共通するのは、OPで誰に対するログアウトなのか(またはどのRPに対してログアウトを指示しなければならないのか)を特定しなければならないという点。場合によっては再認証しなければならないけれど、セッションが切れても、どのRPに対してPositive Assertionを返したを記憶していなければならないということになる。OPのセッションタイムアウトを長くすればいいという問題でもない。

結論

まだまだ十分に検討し尽くされてないな−。でも、実装したい人は、出来るだけライブラリの内側の挙動は変更せずに、エンドポイント分けるとか、OPの改修で吸収するとか、気を遣えば実現できそうな気もします。

おしまい。