Wassr の OpenID でログインできない (RPでのメッセージ検証)
Wassr が実験的に OpenID の発行サイトになっていることを知ったので、試しに Rails OpenID Example RP へログインしてみようとしたら失敗しちゃった。 OP から RP へ戻ってきたときに、以下のエラーメッセージが表示される。
Verification failed: No matching endpoint found after discovering http://wassr.jp/user/machu
なぜだろうと思ったので、ちょっと調べてみた。
RP 側のログを取得
Rails の RP サンプルをローカルで起動して、先ほどと同じように Wassr からログインしてみた。 やっぱり同じエラーが表示される。 RP が出力するログにはもう少し詳細な情報が残っていた。
Discovery verification failure for http://wassr.jp/user/machu * Endpoint mismatch: OP Endpoint mismatch. Expected http://wassr.jp/open_id/trust, got http://wassr.jp/open_id/auth
これはこないだ行ってきた Liberty セミナーで聞いた「OpenID レスポンスメッセージの検証」に関係しているっぽいなぁ。 メッセージ検証の時に /open_id/trust を期待していたけど、 /open_id/auth が返ってきたよ、と。
OpenID の仕様を確認する
今の時点では RP が悪いのか OP が悪いのか良く分からないので、 OpenID の仕様を確認する。 レスポンスの検証はいくつかやることがあるけど、関係してそうなのは 11.2. Verifying Discovered Informationかな。
If using a discovery mechanism that yields an XRDS document, the protocol version, OP Endpoint URL and the OP-Local Identifier (if different than the Claimed Identifier) MUST be present in one <xrd:Service> element. There MAY be unused fields in that <xrd:Service> element.
「OP Endpoint URL」と「OP-Local Identifier」は、 OP の XRDS 内の <xrd:Service> と同じものじゃないといけないと書かれている。
ログから OP Endpoint URL を確認する
再び RP サンプルのログを見て、OP からのレスポンスの内容を確認する。
"openid.op_endpoint"=>"http://wassr.jp/open_id/trust"
エラーメッセージの内容と同じく、 Endpoint URL のパスが /open_id/trust になってる。
XRDS の <xrd:Service> を確認する
Wassr が公開している XRDS 文書を取得して、 OP Endpoint URL と一致するかどうかを確認する。 自分で書いた記事だけど、OpenIDプロトコルの特徴−DiscoveryとSREGを参考にした。
ClaimedID の HTTP ヘッダから XRDS の場所を取得する。
$ curl --head http://wassr.jp/user/machu | grep XRDS X-XRDS-Location: http://wassr.jp/open_id/signon.xrds
次に XRDS の中身を確認する。
$ curl http://wassr.jp/open_id/signon.xrds <?xml version="1.0" encoding="UTF-8"?> <xrds:XRDS xmlns:xrds="xri://$xrds" xmlns:openid="http://openid.net/xmlns/1.0" xmlns="xri://$xrd*($v*2.0)"> <XRD> <Service priority="0"> <Type>http://specs.openid.net/auth/2.0/signon</Type> <URI>http://wassr.jp/open_id/auth</URI> </Service> </XRD> </xrds:XRDS>
Service の中の URI は http://wassr.jp/open_id/auth になっている。 これもエラーメッセージの内容と同じ。
まとめ
OP からのレスポンスに含まれる OpenID Endpoint URL と、 ClaimedID (http://wassr.jp/user/machu) から取得した XRDS 内の OP の URL が一致しないので、レスポンスが偽造されていると判断しているみたい。 個人的には MAC の検証だけで十分じゃないかなと思うけど、ここまで確認するように仕様で定められている (MUST) ということは何か理由があるんだろう。
ちなみに、 Wassr から Fast ladder や LiveJournal! へは普通にログインできたので、ここまで確認していない RP が多いんだろうか。 もしかしたら LiveJournal は OpenID 2.0 に未対応なのかも。