at posts/single.html

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 ladderLiveJournal! へは普通にログインできたので、ここまで確認していない RP が多いんだろうか。 もしかしたら LiveJournal は OpenID 2.0 に未対応なのかも。

関連する日記