OpenID の仕様 動作の概要

OpenID 用語集に引き続いて、OpenID: Specsから仕様の概要を把握。以下はOpenID: SpecsのOverviewの日本語訳。

Step 1 : 自分の Identity URL を作成

あるURLを、OpenIDのIdentityとして利用するためには、そのURLが、どのOpenID Serverでオーソライズされるかを宣言する必要があります。Identity URLとOpenID Serverは、まったく別のサービスでもよいので、Identity URLのホストがOpenIDをサポートする必要はありません。

例として、自分が利用したい Idenity URLが自分のブログのURL(http://bob.com/)だった場合、Bob.comの<head>に、以下のような<link>タグを配置します。

<link rel="openid.server" href="http://bob.com/openid-server.app">
注意
  • 宣言された openid.server URLには、クエリーパラメーターが付加されている場合があります。また、追加でクエリーを追加できるように考慮されている必要があります。(例:?マークを2度つけないなど)
  • Pingbackの仕様におけるlinkタグの制限を参考(Pingback 1.0
    • openid.server URLは、絶対URLでなくてはいけない。OpenID consumersは、相対URLを処理しようとしてはいけない
    • openid.server URLは、&amp;, &lt;, &gt;, and &quot; 以外のエンティティを含んではいけない。HTMLでvalidではない、あるいはドキュメントの文字エンコーディングに含まれない、すべての文字は、RFC2396に基づいて、%xx のようにエスケープされる必要がある。

認証を移譲する(Delegating auth)

誰か他の人が管理する OpenID serverを、自分のウェブサイトについて情報を知らせること無く、利用することが可能です。

例えば、 http://bob.com/を自分のIdentityとして使用する場合に、自分でOpenID serverを持つ必要はありません。そのかわりに、LiveJournalのアカウントを取得すれば、LiveJournalがOpenID serverを提供するので、http://bob.livejournal.com/ などのLiveJournalのURLを利用して、bob.comをidentityとすることができます。

bob.comを自分のIdentityとして利用し、実際には http://bob.livejournal.com/ で認証するには、以下のようにbob.comで宣言します。

<link rel="openid.server"   href="http://www.livejournal.com/openid/server.bml">
<link rel="openid.delegate" href="http://bob.livejournal.com/">

この内容を consumer が確認し、openid/server.bml と会話して、bob.comを意識せずに、bob.livejournal.comかどうかを確認します。

この方法のいい点は、OpenID identityを何年も変わらず保持できることです。OpenIDとして使う Serverを変えたり、自分のServerを持つこともできます。

Step 2 : Userが"claimed(自分が主張する) identity"を送信

End Userが、OpenIDをサポートするConsumerのWEBサイトを訪れます。ConsumerのWEBサイトには、「OpenIDで認証してコメントをしてください」というように書いてあるので、Userは "bob.com"と入力します。

Login with your blog URL:
For example: happygirl.bloghost.com

Userは、"http://" や、最後の "/"を省略できることに気をつけてください。Consumerは、URLを適切な標準URLフォーマットに変換し、リダイレクトなどで最終的なURLを通知します。標準化されたURLは、UserのIdentity URLとなります。

また、Formフィールドは、" openid_url "と名前付けされていることが推奨されます。それによって違うWEBサイトでも、ブラウザの入力補完によってURLが自動入力されます。この手法は、eコマースのサイトなどが"address1"や"address2"などの入力フォーム名をつけて、入力の手間を軽減しているのと同じ方法です。

この段階では、まだ認証がされていないので、"claimed(自分が主張する) identity"と呼ばれます。

Step 3 :Consumer のwebサイトがidenitiy URLを識別

ConsumerのWEBサイトは、ユーザーが入力したドキュメントを、(多分キャッシュから)取ってくる必要があります。この時に、悪意のあるユーザーが、内部ネットワークに接続しようとするなど、アタックの可能性があるので、search.cpan.org: Brad Fitzpatrick / LWPx-ParanoidAgentなどの、かなり慎重なチェックをするHTTP libraryを使った方がよいでしょう。

Consumerは、その後にheadをパースして、"openid.server"と、オプションになる"openid.delegate"の宣言を探します。(Consumerは、openid.delegate をサポートしなければいけません)

Step 4 : [オプション] ConsumerのWEBサイトが、server URLと関係を構築

プロトコルは、Consumerの能力に応じて"smart mode"と"dumb mode"の両方をサポートします。"smart consumer"は、後の作業のために、最初にもう少し処理をして情報を保持します。そのかわり、ステート情報をローカルにキャッシュする必要があります。"dumb consumer"は完全にステートレスです。そのかわりに追加のHTTPリクエストを必要とします。

もし可能であれば、Consumerが最初に openid.mode=associate POSTリクエストを、Identity serverに送信して、"shared secret"を取得することが推奨されます。この"shared secret"は、HMAC-SHA1 keyとして将来的なidentity チェック・リクエストに使用されます。もし Consumerが、期限が切れていない"shared secret"を既に持っている場合は、それを利用します。

The shared secret can be exchanged either in plain-text or encrypted with a Diffie-Hellman-negotiated secret. Not that if Diffie-Hellman is used, it's only used in the associate mode. The identity check modes assume you already have some shared secret, regardless of how you got it.

Step 5 : Consumerが、User-Agentを介してIdentityをチェック

Consumerは、Identity serverの、openid.mode=checkid_immediate (あるいは checkid_setup)のURLを生成して、User-Agentをそこに転送します。User-Agentが転送されることで、Cookieに保存されていたり、あるいはログイン処理を通じてIdenity Serverで確認がおこなわれます。サーバーがその処理をおこない、結果をreturn_to_URLに追加して、User-Agentを、Consumerに再度、転送します。

以上が概略ですが、詳しい仕様などはOpenID: Specsを参照。

上の記事で使っていた仕組みの概略は理解できました。あとは、実際のサービスでの実装などをみながら、もうちょっと特徴を把握した方がいいかもですね。Consumerの側で、Identityのリストを管理すると、URLをベースにしたオープンなSNSっぽく使えるのでしょうか。Bloglinesで購読しているブログのURLをOPMLで取得して、登録してあるBlogのドメインのIdentityからのみ、何かの操作を許可するとか。分かりやすいのはブログ記事へのコメントなんだろうけれど、もうちょっと何かMash-up的なことがやれると新しいかな〜という気もします。シンプルで基本的な認証インフラなので、あとはアプリケーションの工夫次第ってところでしょうか。