Windows Live ID OpenID Provider CTP リリース ということもあり、OpenIDの認証に対応したサイト作るにはどうするのかなーとちまちま調べていたりします。具体的なことについては意外と情報すくないんですね。ライブラリはあるけど。しかたがないので本家、Final: OpenID Authentication 2.0 - Final を読んでます。日本語の記事では、OpenID Authentication 2.0時代の幕開け - @IT が良かった。
とりあえずLive IDを使った認証ができるようにしたい(それができる、ほぼイコール2.0対応OpenIDプロバイダーに対応できたことになるけど)。OpenID 2.0では、ユーザーは「open.live-int.com」のようなOpenIDプロバイダーを表すURLを入力するだけで認証が可能になってます。この値はユーザーごとに異なるわけではないので、Live IDのOpenIDで認証するサイトにしてしまえば、そのサイトでユーザーが認証のために入力する必要さえもなくなるわけですね。実際、すでに2.0対応のOpenIDプロバイダーのYahooは、Yahoo IDでログインするためのボタン画像を提供しています→ Yahoo!デベロッパーネットワーク - Yahoo! JAPAN IDログインボタン
さて、まだ認証一連の流れで初めの部分しかできていないのだけど「openid.live-int.com」などのURLからWebサイトがアクセスすべき認証用のURLを取得するところまでは書いてみた。ちなみに、OpenIDでの認証はいろいろパターンがあるのでその1例です。あと書いている内容、間違ってるかもしれません。
これからする処理は、Final: OpenID Authentication 2.0 - Final の Discovery 部分の処理になります。ユーザーが入力した値からOpenIDプロバイダーに対して認証のリクエストに必要な情報を探すところですね。
まず「openid.live-int.com」という情報から始めます。これは「http://openid.live-int.com/」と変換します。このようなURLの場合、Yadisプロトコル使えとあります。XRDS文書と呼ばれるXMLベースのテキストを取得します。上記OpenID仕様のURLにある参考URLからYadisプロトコルを読むと、GETかHEADメソッドでリクエストして、レスポンスのX-XRDS-Locationヘッダをみろとあります。リクエスト時にはAcceptヘッダにapplication/xrds+xmlを指定するともありました。
Dim url = "http://openid.live-int.com/"
Dim request As HttpWebRequest
Dim response As HttpWebResponse
Dim xrdsLocation As String
' First Request
request = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
request.Accept = "application/xrds+xml"
request.Method = "HEAD"
response = DirectCast(request.GetResponse, HttpWebResponse)
xrdsLocation = response.Headers("X-XRDS-Location")
というわけで、以上のコードになります。xrdsLocationには「http://openid.live-int.com/OpenIDXRDS.srf」が入ります。レスポンスのContentTypeはtext/htmlでした。GETメソッドによりHTMLの内容を取得した場合、それをパースするとこの時点でほしいURLが記述されているんですよね。さらに、ContentTypeがxrds+xmlだった場合、これから次の手順で行うことがすでに完了したことになるのかな。いろいろと考慮するところは多いです。
ここでは、とりあえず取得できたアドレスにアクセスします。そして、実際に受け取る内容は次のようになります。
<?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/server</Type>
<URI>https://openid.live-int.com/OpenIDAuth.srf</URI><LocalID>http://specs.openid.net/auth/2.0/identifier_select</LocalID></Service>
</XRD>
</xrds:XRDS>
このURIを使えば良いみたいですね。Serviceが複数あったりする場合もあるので、ここでも考慮事項は多そうです。コードはこんな感じ。
'Imports <xmlns:xrds="xri://$xrds">
'Imports <xmlns="xri://$xrd*($v*2.0)">
' Second Request
request = DirectCast(HttpWebRequest.Create(xrdsLocation), HttpWebRequest)
request.Accept = "application/xrds+xml"
request.Method = "GET"
response = DirectCast(request.GetResponse, HttpWebResponse)
Dim content = ""
Using stream = response.GetResponseStream, _
reader = New System.IO.StreamReader(stream, System.Text.Encoding.UTF8)
content = reader.ReadToEnd
End Using
Dim xml = XDocument.Parse(content, LoadOptions.SetBaseUri)
Dim uri = xml.<xrds:XRDS>.<XRD>.<Service>.<URI>.Value
この後、実際にユーザーの認証処理に進んでいくわけですがまだまだ遠いなぁ。