日向夏特殊応援部隊

俺様向けメモ

YadisとOpenIDの関係 (2) - Yadisプロトコル

d:id:ZIGOROu:20080214:1203011300の続きです。

Yadisプロトコルを知ろう

Yadis 1.0 (HTML) - The Yadis Protocolがテキストですが、仕様なので多少冗長なので要点だけ抑えていきましょう。

何のためにYadisプロトコルがあるのか

Relying Partyが、そのユーザーのYadis IDで使えるサービスを記述したYadis Resource Discriptorを得る為にあります。

もっと噛み砕いて言えばそのユーザーのYadis文書がどこにあるのかを調べる為の手続きです。

何故Yadis Resource Descriptorが必要なのか

与えられたYadis ID(それがURLならYadis URL)で使える認証サービスがどれなのかをRPが知る為にあります。ここで言う認証サービスはOpenIDだったりLIDだったりSAMLだったりします。

で、そもそもYadis Resource DescriptorってのはほとんどYadis文書(XRDS文書)と同じ意味です。(d:id:ZIGOROu:20080214:1203011300 を参照)
このYadis文書に、そのユーザーの認証を行えるサービスが複数記述出来たり、認証以外にもIDベースで使えるサービス(例えばプロフィール属性交換とか)があればそれを記載出来ます。

Yadisプロトコルの流れ

ざっくり言えば下記のようになります。

  • Yadis IDをユーザーがRPに教えます
  • RPはYadis IDで示されたURLにアクセスします

で、このYadis IDにアクセスするメソッド(GET/HEAD)で必要に応じて、最大2回追加のHTTPリクエストを行う必要があります。

最初のリクエス

RPはユーザーから与えられたYadis URLに実際にアクセスします。
GETでもHEADでも構いません。

そのときのレスポンスにバリエーションがあって、

  • meta要素でhttp-equivを使ってx-xrds-locationを設定しているhtmlが返って来る
  • x-xrds-locationレスポンスヘッダを含んでいる
  • レスポンスヘッダのみで、x-xrds-locationレスポンスヘッダを含んでるか、content-typeがapplication/xrds+xmlの場合。あるいは両方
  • 文書のmimetypeがapplication/xrds+xmlであるもの

になります。

で、元々の目的はYadis文書を得る事だから最後のmimetypeがapplication/xrds+xmlの場合はGETでアクセスしてる場合は目的を達しているので、そこで終了になります。

それ以外の場合は、

  • x-xrds-locationが指定されてるなら、そこで指定されてるURL
  • content-typeがapplication/xrds+xmlでHEADでアクセスしてるか、レスポンスボディが無い場合は与えられたYadis URL

に対してそれぞれ再度GETリクエストを送る必要があります。

また最終的にapplication/xrds+xmlな文書が欲しい訳ですから、Acceptリクエストヘッダでapplication/xrds+xmlを追加指定しておけば、YadisのIdPはそれを解釈して直接XRDS文書を返してくれるかもしれません。*1

二番目のリクエス

先に挙げた2パターンのリクエストを送るケースがあるのですが、元々のリクエストがHEADで、二番目のリクエストはGETに換えただけの場合で、x-xrds-locationが(レスポンスヘッダまたはmeta要素で)指定されている場合は改めて、そのURLにGETでアクセスしなければならない。
そのリクエストが3番目のリクエストです。

三番目のリクエス

これはもうXRDS文書であることが保障されているはずなので、このリクエストに対するレスポンスが正しくXRDS文書であるならば、正常に終了と言う事になります。

どれをXRDS文書またはXRDS文書の所在とすべきかの優先順位
  • x-xrds-locationレスポンスヘッダで指定されてるURL
  • meta要素でx-xrds-locationが指定されてる場合
  • レスポンス本文がapplication/xrds+xmlの場合

の順番です。

OpenIDとYadisプロトコルの関わり

Yadis ID(Yadis URL)はOpenIDで言う所のClaimed Identifierと一致するケースがほとんどでしょう。
Claimed Identifierで表されたURL(またはXRI)は、何らかの形でXRDS文書を返すようにする方が、OpenID Authentication 2.0では優先されており、link要素でOP EndPoint URLを指定するのは小学生までな訳です。

Claimed IdentifierだろうがOP Identifierだろうが、XRDS文書を返した方が互換性の高い実装となると思います。
また他に何のサービスが使えるかをRPに教える事が出来ると言う点も大きいです。

link要素ベースの探索だと認証をする為だけの用途になってしまう訳ですね。

まとめ

Yadisプロトコルを実装するならHEADは使わない方が良いと思います。
GETで始めからアクセスしてれば最大2回のリクエストで済むからです。

また実装に当たっては、

  • Acceptヘッダを必ず見て、application/xrds+xmlが指定されていれば優先的にXRDS文書を返すようにする
  • そうでなければレスポンスヘッダにx-xrds-locationを指定する

のが綺麗な実装なのかなと思います。


次はXRDS文書の中身を書く予定です。

*1:と言うかIdPは、そう実装すべきですね。