OpenID × XAuthのユースケースを考えた

今回はXAuthとOpenIDの組み合わせたユースケースについて考えてみました。
以下の2点です。

  • ユーザー認証状態の突き合わせ
  • シングルログアウト

ユーザー認証状態の突き合わせ

OP単位の認証情報を取得することがXAuthのJSにより簡単にできることはわかっていますね。
では、XAuth Tokenにセッションを識別(マッチング程度)できる文字列を載せておくと便利なのではないでしょうか?
導入例を考えてみます。

認証時

  • RPは認証要求時に"xauth-sessionid"を欲しがっていることを伝えるExtensionパラメータを含む
  • OPはログイン成功時にログインセッションIDに紐づいた一意な文字列を作成し、その文字列をXAuth Tokenとして発行
  • OPは認証応答時にxauth-sessionidのようなパラメータでXAuth Tokenの文字列を含む
  • RPは認証応答を処理するタイミングで、自らのログインセッションにその文字列を含む

RP上で重要な処理を行うとき/ある程度時間がたったとき

  • RP上で重要な処理をさせるときに、XAuth Tokenを取得
  • RPはOP上のログインセッションが変わっていないかどうか、自らが管理している"xauth-sessionid"の値をつき合わせて確認
  • "xauth-sessionid"の値と変わっていたとき、OP上でユーザーが変わった可能性があるため、もう一度OpenID認証要求を送る

これで、RPとしてはログインセッションを長くしても、OP上のユーザー状態を判別して第3者にサービスを提供してしまうことを防ぐことが可能になるかもしれません。

シングルログアウト

上記の"xauth-sessionid"を使って、ログアウトをさせましょう。

OP上でユーザーがログアウトした/されたとき

  • OPがXAuth TokenをExpireさせる

RP上で重要な処理を行うとき/ある程度時間がたったとき

  • RP上で重要な処理をさせるときに、XAuth Tokenを取得
  • XAuth Tokenの値が空になっていたら、RPはユーザーをログアウト扱いにする

OPからRPへPushする形式ではないにしろ、RPがリアルタイムでOP上のユーザー状態を把握できるしくみとして使えそうです。

まとめ

  • XAuth Tokenと組み合わせることでUX改善ができるかもしれない
  • XAuth Tokenの発行/無効化など、OpenIDの認証以外のタイミングで行われる処理があるため、仕様としてまとめようとすると少し大変かも

(おまけ)OpenID UI Extension : Experimental Mode

YDNのPOSTに以下のようなことが書いてありました。

The concepts behind XAuth have already been explored in the experimental x-has-session API defined in the OpenID User Interface Extension, which has already been implemented by some providers.

http://developer.yahoo.net/blog/archives/2010/04/xauth_oauth_and_yahoo_openid.html

OpenID UI Extensionに、以下のような記述を見つけました。
これはXAuthの話とは別ですが、OP上の認証状態をRPが判別できればUIを最適化できるかもといった内容です。

Appendix A. Example Use of Experimental Mode

In OpenID authentication, when using the checkid_immediate mode, there is no mechanism to indicate that there is a user logged in at the OpenID Provider.
Therefore, the Relying Party does not know if the checkid_immediate request failed because:

1. The user does not have an account at the OpenID Provider (or is not logged in at the Provider), or:
2. The user is logged in to the OpenID Provider but has not yet approved transparent login with the Relying Party.

This makes it difficult for the RP to optimize the OpenID user experience by, for instance, displaying a prominent button for the OpenID Provider in case (2).
The following example shows how an experimental mode can be sent with checkid_immediate requests to obtain this information.

openid.ns.ui
REQUIRED. Value: "http://specs.openid.net/extensions/ui/1.0"
openid.ui.mode
REQUIRED. Value: "x-has-session".

To respond, the OpenID provider sends identical parameters in the "setup_needed" response to answer affirmatively (i.e., there IS an authenticated browser session):

openid.ns.ui
REQUIRED. Value: "http://specs.openid.net/extensions/ui/1.0"
openid.ui.mode
REQUIRED. Value: "x-has-session".

Alternative, if the OpenID provider needs to indicate the LACK of a session, it sends simply the UI namespace, without a mode, in the "setup_needed" response:

openid.ns.ui
REQUIRED. Value: "http://specs.openid.net/extensions/ui/1.0"

http://svn.openid.net/repos/specifications/user_interface/1.0/trunk/openid-user-interface-extension-1_0.html#anchor11

【書いてある内容】

  • 現在の仕様では、RPがOPにcheckid_immediateモードで認証要求を送り失敗したとき、理由が分からない
  • 単純にログインしていないかもしれないし、拒否っているかもしれない(そもそもOPが対応してないかもしれないけど)
  • RPは"ユーザーがOP上でログイン状態であるかどうか"を教えてもうためにcheckid_immediateモードの認証要求を送る際に、namespaceとmode=x-has-sessionというパラメータを送る
  • ユーザーがログイン状態だけどcheckid_immediateモードの処理ができない場合は、OPはレスポンスにnamespaceとmode=x-has-sessionを返す
  • ユーザーがログイン状態でないとき、OPはレスポンスにnamespaceのみを返す

なるほど、これでRPはcheckid_immediateモード失敗時にユーザーの認証状態を知ることができるということですね。
これをどこが実装しているのか、とうやら"Google"のようです。
仕様ドキュメントにありました。

User interface extension:

openid.ui.mode :

(optional) Specifies the alternative user interface. The following values are valid:
* "popup"
* "x-has-session" (used to indicate the presence of an authenticated session)
Additional modes may be supported in the future.

http://code.google.com/intl/ja/apis/accounts/docs/OpenID.html#Parameters

試してみました。

# リクエス
https://www.google.com/accounts/o8/ud
?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0
&openid.realm=http%3A%2F%2Fr-weblife.sakura.ne.jp%2Flibraries%2Fphp-openid-2.1.3%2Fexamples%2Fconsumer%2F
&openid.mode=checkid_immediate
&openid.return_to=http%3A%2F%2Fr-weblife.sakura.ne.jp%2Flibraries%2Fphp-openid-2.1.3%2Fexamples%2Fconsumer%2Ffinish_auth.php%3Fjanrain_nonce%3D2010-05-02T06%253A19%253A58ZKRaJka
&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.ns.ui=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fui%2F1.0 ★
&openid.ui.mode=x-has-session ★

# ログイン状態のときのレスポンス
http://r-weblife.sakura.ne.jp/libraries/php-openid-2.1.3/examples/consumer/finish_auth.php
?janrain_nonce=2010-05-02T06%3A19%3A58ZKRaJka
&openid.mode=setup_needed
&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0
&openid.ns.ext1=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fui%2F1.0 ★
&openid.ext1.mode=x-has-session ★

# 未ログイン状態のときのレスポンス
http://r-weblife.sakura.ne.jp/libraries/php-openid-2.1.3/examples/consumer/finish_auth.php
?janrain_nonce=2010-05-02T06%3A19%3A58ZKRaJka
&openid.mode=setup_needed
&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0
&openid.ns.ext1=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fui%2F1.0 ★

動いてますね。