第3回 Consumerの実装を知り、OpenIDを使ってみよう:OpenIDの仕様と技術(3)(1/3 ページ)
前回まではOpenIDの基礎知識として、根底にある考え方や用語を中心に解説してきました。今回はその準備を踏まえ、Perl、Catalystを活用し実際にConsumerサイトを構築してみましょう。(編集部)
今回から実際にOpenIDを利用したサイトを構築するために必要な知識について触れたいと思います。まずはConsumer側の実装から探っていきましょう。
なお、サンプルはOpenIDにゆかりの深いPerlで記述します。サンプルは主にLinuxでの動作を想定しています。
Net::OpenID::Consumerモジュールのインストール
Perlを用いたOpenIDのConsumer実装としては、OpenIDの提唱者の1人、ブラッド・フィッツパトリック氏が作ったNet::OpenID::Consumerモジュールがあります【注1】。まずはこのモジュールを使っていきましょう。
【注1】
ほかの実装としてはNet::OpenID::JanRain::Consumerがあります。このモジュールはジャンレインが提供するOpenID対応のサイトで実際に使われているモジュールのようです。
Perlの知識のある方は斜め読みでも構いませんが、ご存じでない方もいらっしゃるかと思うので、まずはインストールから説明しましょう。またこのモジュールが依存しているモジュールのインストールに若干バッドノウハウがあるので、その点についても触れていきます。
Perlモジュールのインストールはcpanコマンドを用いるのが一般的です。従って、一般的なインストール方法としては、
$ sudo cpan -i Net::OpenID::Consumer
を実行します。しかし依存しているCrypt::DHというDiffie-Hellman鍵共有を実装したモジュールと、そのCrypt::DHモジュールに依存しているMath::BigIntモジュールに関して、若干補足すべき点があります。
Crypt::DHモジュールのソースを見てみると、6行目にMath::BigIntモジュールのuse宣言があります。
use Math::BigInt lib => "GMP,Pari";
行末の指定は、Math::BigIntの実装モジュールの優先順位の指定です。このモジュールはちょうどオブジェクト指向でいうdelegateになっていて、実装の選択ができるようになっています。よって、
という順に実装モジュールがあるかどうか試行していき、存在しているモジュールを採用する流れになっています。
ここで注意しなければならないのは、デフォルトで採用される実装モジュールであるMath::BigInt::Calcは速度に問題があります。そのため、正しく動作はしますが使用は避けた方がよいでしょう。従って、次の順番でcpanコマンドを入力していくと、すんなりインストールが行えるはずです。
$ sudo cpan -i Math::BigInt $ sudo cpan -i Math::BigInt::GMP $ sudo cpan -i Crypt::DH $ sudo cpan -i Net::OpenID::Consumer
これでインストールは完了です。
Net-OpenID-ConsumerのAPI
Net-OpenID-ConsumerのAPIの動作は、公開されているシノプシスを見れば、どう書くと何ができるか把握することができるかと思います。Net-OpenID-Consumerにはいくつかのモジュールが含まれていますが、主要なものだけ簡潔に解説していきたいと思います。
●Net::OpenID::ConsumerモジュールのAPI
基本的にはユーザーが直接使うのはこのNet::OpenID::Consumerモジュールのみで、ほかのモジュールは間接的に使うか、結果として取得できるオブジェクトとなります。
・ ua()メソッド
Perlの代表的なhttpクライアントモジュールであるLWP::UserAgentモジュール、またはそのサブクラスのインスタンスへのゲッター/セッターです。暗黙の了解としてPerlモジュールではJavaのような言語とは違って、冗長な記述で書かれていることが多く、ゲッター/セッターがメソッドとして同じ名前で存在していることがほとんどです。
・cache()メソッド
ゲッター/セッターメソッドです。get($key), set($key, $value)といったメソッドを持つオブジェクトならば、基本的には何でも使えます。暗黙の了解として、packageの接頭辞にCache::が付くモジュールはほとんどすべてこの条件を満たしています。
・consumer_secret()メソッド
ゲッター/セッターで、Consumer側の秘密鍵になります。この秘密鍵はスプーフィング(なりすまし)を防ぐために使うナンス(nonce)の自己署名のために使います。タイムスタンプなどを利用した値を用いた方が安全性が高まります。また255bytesを超える値を採用してはいけません。
・args()メソッド
渡されたCGIパラメータへのアクセサです。PerlでのCGIパラメータの取り扱いはさまざまな手法が存在しますが、主要なものにはすべて対応しています。
・required_root()メソッド
認証サーバからリダイレクトで戻ってくるConsumer側のreturn_urlのプレフィクスを指定します。これもスプーフィング対策です。
・claimed_identity()メソッド
ユーザーの入力したURLからNet::OpenID::ClaimedIdentityオブジェクトを返します。そのURLがOpenIDに対応したURLで無い場合はundef(Perlの未定義値)を返します。
・user_setup_url()メソッド
checkid_immediateモードでのアクセスが失敗した場合に返ってくるURLの値を返します。このURLが提供する機能は認証そのものや、信頼性の確立に関するいかなるものも対象となります。
・user_cancel()メソッド
認証サーバからの戻り値としてopenid.modeがcancelだった場合はtrueになります。具体的には、checkid_setupによって認証サーバにリダイレクトした後に、End Userが自分のIdentifierをConsumerに共有させたくない場合に、多くの場合「キャンセル」ボタンが存在し、それを押した際に、openid.modeがcancelとしてConsumerに通知されます。
・verified_identity()メソッド
認証済みのIdentifierとしてNet::OpenID::VerifiedIdentityオブジェクトが返されます。dumbモードではcheckid_authenticationも実行します。
・err()メソッド
“errcode: errtext”というフォーマットで、最後に起きたエラー内容を返します。
・errcode()メソッド
最後に起きたエラーコードが返ってきます。
・errtext()メソッド
最後に起きたエラーテキストが返ってきます。
・json_err()メソッド
最後に起きたエラー内容をJSON形式で返します。checkid_immediateのようにiframeなどによるAjaxを使ったアクセスを行う場合に利用します。
Net::OpenID::ClaimedIdentityモジュールのAPI
Net::OpenID::Consumerのclaimed_identity()メソッドの戻り値として、Net::OpenID::ClaimedIdentityオブジェクトを取得します。実際のClaimed IdentifierであるURLをclaimed_identity()メソッドに渡したときに、そのURLがOpenID対応であればこのオブジェクトを返します。このモジュールのAPIで特に重要なのはcheck_url()メソッドです。
・claimed_url()メソッド
Claimed IdentifierであるURLを返します。
・identity_server()メソッド
IdP(Identity Provider)のエンドポイントURLを返します。
・check_url()メソッド
associateの実行(smartモード時のみ)とcheckid_immediateまたはcheckid_setupを実行するためのURLを生成し、返します。
以上がNet-OpenID-Consumerディストリビューションで、ユーザーが主に利用する主要なAPIになります。
先にAPIを説明してしまいましたが、いくつか見慣れない用語や詳しく解説していない用語が出てきたと思います。その中で注目すべきトピックとして、
- Diffie-Hellman鍵共有
- openid.mode
- associate、checkid_immediate、checkid_setup、checkid_authentication
が挙げられるかと思います。
Diffie-Hellman鍵共有や、LWP::UserAgentのサブクラスといったものはOpenIDのセキュリティモデルに関するトピックです。詳しくはまた別の機会で触れることとし、今回はConsumer側の実装を行ううえで必ず知らねばならない、OpenIDの動作モードに関して説明していきます。
Copyright © ITmedia, Inc. All Rights Reserved.