ブログ  前の記事  次の記事  2008-01-04 

たけまる / 複数の OpenID を切り替えて使うときの振る舞い


2008-01-04

_ 複数の OpenID を切り替えて使うときの振る舞い [openid]

細かいことですが,ひとつの IdP が提供する複数の OpenID を切り替えて
使うような状況では,IdP の振る舞いが定められてないかもしれません
(仕様バグ?).

たとえば,仕事とプライベートで異なる OpenID を使い分けるような状況
です.いくつかの IdP でテストしてみたところ,エラーや不自然な振る
舞いが見られました.

原因を分析して,解決方法を考えてみました.

# まだ Open Problem なら,open-id ML に投げてみようかなぁ.

(2008-01-05追記) machu さんから,シングルログアウトとの関係について
コメントいただきました.ありがとうございます.
シングルログアウトがないよって話かな?
確かに,シングルログアウト (Consumer と IdP で同期を取ってログアウ
トすること) との関係から説明した方がいいですね.違いがわかりにくかっ
たので,補足します.

このエントリで書いている問題は,シングルログアウトが完全に実現され
れば自動的に解決します.しかし,シングルログアウトを実現するのは
現在の仕様では難しいです.というのは,ユーザがConsumerからログアウ
トしたときに,そのことをIdPに通知するプロトコルが存在しないためで
す (参考↓).
OpenID におけるセッション管理 - tkudo's weblog about identity management

そこで今回は,「シングルログアウト」ではなく,「再ログインの同期」
のみに状況を絞って,簡単に実現する方法を提案しています.

今回取り上げている問題では,ユーザはConsumerからログアウトした後に,
異なるユーザ名でIdPに再アクセスします.この場合,IdPは,ユーザが
Consumerからログアウトしたことを知ることができます (たとえば,
Cookie と openid.identitiy= の不一致でわかる).であれば,IdPの実装
を少し工夫するだけで,Consumer側のログアウトをIdP側にも反映させるこ
とができます.
(追記ここまで)


■ 問題の再現方法

ひとつの IdP から複数の OpenID を取得します.今回は livedoor と
Vox でテストしました.

適当な Consumer に 1つめの OpenID (例 http://example.com/foo) でロ
グインを試みます.すると,IdP に redirect されるので,ユーザ名 (foo)
とパスワードを入力します.そして,Consumer に redirect されます.

次に,Consumer からログアウトし,2つめの OpenID (例 http://example.com/bar)
でログインを試みます.予想では,ユーザ名 (bar) とパスワードの入力
を求められると思っていました.

ところが,livedoor では「認証に失敗しました」というエラーが表示さ
れます.

Vox では,1つめのユーザ名 (foo) でログインした Vox サイトがされま
す (Consumer に redirect されることもありません).

(2008-01-09追記) はてなで試したら,「現在ログイン中のユーザではあ
りません」という的確なエラーが返ってきました.

ユーザとしては,1つめのユーザ名 (foo) はログアウトし,2つめのユー
ザ名 (bar) とパスワードを入力することを期待するように思います.

■ 原因の分析

OpenID では,ユーザが IdP にログインしていなければ,次のような処理
が行われると思います.ここでは,IdP でのユーザ名を foo とし,
OpenID を http://example.com/foo として説明します.

未ログイン状態での正常な処理
0. ユーザは,IdP にログインしていない
1. ユーザは,Consumer サイトで OpenID (http://example.com/foo) を入力
2. Consumer は,association などを行った後,ユーザを IdP に redirect
3. IdP は,ユーザがログイン状態かどうかをチェック
4. 未ログイン状態であれば,IdP は,ユーザを Setup URL に redirect
5. ユーザは,ユーザ名 (foo) とパスワードを入力
6. IdP は,ユーザ名 (foo) とパスワードをチェック
7. OK であれば,ユーザを Consumer (return_to URL) に redirect

3. でログイン状態をチェックするときに,ユーザが異なるユーザ名でログ
インしていると,問題が発生します.

異なるログイン常態でのおかしな処理
0'. ユーザは,ユーザ名 bar で IdP にログインしておく
1.  ユーザは,Consumer サイトで OpenID (http://example.com/foo) を入力
2.  Consumer は,association などを行った後,ユーザを IdP に redirect
3.  IdP は,ユーザがログイン状態かどうかをチェック
4'. ユーザ名 bar でログイン状態であるが,要求 OpenID は
    http://example.com/foo であるため,IdP は混乱する

■ 「シングル再ログイン」の実現方法

[2007-12-30-1] で紹介した Idp 実装では,次のようにして問題を解決し
ています.

まず,/logout というページを用意します.このページにアクセスすると,
ログアウト処理を行った後に /login に redirect するようにしておきま
す.クエリ変数があれば,それらは引き継ぎます.

たとえば,/logout?openid.identity=http://example.com/foo&... にア
クセスすると,ログアウトしたあとに,/login?openid.identity=http://example.com/foo&...
に redirect されるわけです.

この /logout を Setup URL として設定しておきます.

さて,ユーザがアクセスしてきたときに,ログインユーザ名と OpenID が
異なっていたとします.ここで,ユーザは Setup URL に redirect されま
す.すると,ユーザはログアウトした後に /login に redirect されます.
ユーザは未ログイン状態であるため,正常通りに Open ID 処理が行われま
す.

つまり,ログインユーザ名と OpenID が異なっていたとき,IdP はユーザ
をログアウトさせてしまえば良いということです.

これって,すでに OpenID 界隈では議論されているんでしょうか?

一言メッセージをこっそり送信できます (非公開)
 今年の西暦→