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文書の所在とすべきかの優先順位
- 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は、そう実装すべきですね。