検索
連載

第3回 Consumerの実装を知り、OpenIDを使ってみようOpenIDの仕様と技術(3)(3/3 ページ)

前回まではOpenIDの基礎知識として、根底にある考え方や用語を中心に解説してきました。今回はその準備を踏まえ、Perl、Catalystを活用し実際にConsumerサイトを構築してみましょう。(編集部)

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

Catalystを使ってConsumer側の認証プログラムを書く

 今回はCatalystを使ってサンプルを記述していきます。Catalystそのものの使い方については、本記事で取り扱うべき範囲を超えているので必要以上に解説はしません。 またCatalystには、プラグインとしてCatalyst::Plugin::Authentication::Credential::OpenIDというモジュールが存在しますが、今回は学習のため、このモジュールを使わないで実装します。

 今回サンプルソースコードを用意してみました。動作環境はLinux /MacOSXを想定しています。サンプルソースコードをダウンロードし、下記のようにコマンドを入力しましょう。

$ tar xfz OpenID-ConsumerApp-0.01.tar.gz
$ cd OpenID-ConsumerApp-0.01
$ perl Makefile.PL

 この時に必要なモジュールがインストールされていない場合は、

$ sudo make

でインストールされるかと思います。

 さらに使い方ですが、

$ ./script/openid_consumerapp_server.pl -d -r

でdaemonとして起動しますので、ブラウザに http://localhost:3000/ と入力す るとサンプルプログラムを確認する事ができます。起動を停止するにはTERMシグナルをkillで送るか、C-cでSIGINTシグナルを送れば停止します。

【サンプルソースコード】

サンプルソースコードはこちらからダウンロードしてください。

http://www.atmarkit.co.jp/fsecurity/rensai/openid03/OpenID-ConsumerApp-0.01.tar.gz


認証フォームの作成

 Catalystのプロジェクト名を“OpenID::ConsumerApp”で作成したとして以降を進めていきます。OpenID::ConsumerApp::Controller::Rootモジュール内のdefaultメソッドを次のようにします。

sub default : Private {
     my ( $self, $c ) = @_;
     $c->stash->{template} = "index.tt"; 
     $c->forward('OpenID::ConsumerApp::View::TT');
}
リスト1 OpenID::ConsumerApp::Controller::Rootのdefaultメソッド

 ここでforward先にOpenID::ConsumerApp::View::TTを指定していますが、これはCatalyst::View::TTモジュールのサブクラスを指定しています。またstashのtemplateに代入してある値“index.tt”はテンプレートファイルになります。

 localhostでopenid_consumerapp_server.plでCatalystを実行している場合は、http://localhost:3000/にアクセスすることで認証フォームが表示されます。

IdPへの問い合わせ機能の実装

 次にOpenID::ConsumerApp::Controller::Loginモジュールを確認しましょう。その中のindex()メソッドを抜粋します。

sub index : Private {
     my ( $self, $c ) = @_;
     my $csr = Net::OpenID::Consumer->new(
         ua => LWP::UserAgent->new,
         cache => Cache::File->new(
             cache_root => '/tmp/openid',
             default_expires => '6000 sec'
         ),
         consumer_secret => 'zigorou',
         args => $c->req->params,
         required_root => 'http://localhost:3000/',
         debug => 1,
     );
     my $delayed_return = $c->req->param("mode") eq  "checkid_setup" ? 1 : 0;
     $c->log->debug("delayed_return : " . $delayed_return);
     if (my $cident =  $csr->claimed_identity($c->req->params->{openid_url})) {
         my $check_url = $cident->check_url(
             return_to => "http://localhost:3000/login/handler",
             trust_root => "http://localhost:3000/",
             delayed_return => $delayed_return
        );
        $c->res->redirect($check_url);
     }
     else {
         $c->res->body("Can't create claimed identifier  object.");
     }
}
リスト2 OpenID::ConsumerApp::Controller::Loginのindex()メソッド(抜粋)

 Net::OpenID::Consumerモジュールを実際に使う部分となります。この処理の中で必要になる処理をもう一度おさらいしましょう。

  • IdPのエンドポイントURLの抽出(必要ならdelegateの解決)
  • 必要ならばassociateモードの実行
  • checkid_immediateまたはcheckid_setupモードの実行
  • User-AgentをIdPにリダイレクト

 実はこの4つの手続きのうち、最後の1つを除きすべてNet::OpenID::Consumerのcheck_url()メソッドが担当してくれます。そしてcheck_url()の戻り値が、まさに最後のリダイレクト先のURLなので、サーバ側ではそのURLにリダイレクトさせる処理だけ書けばよいことになります。

 また、check_url()メソッドのdelayed_returnパラメータが何を意味するのか理解しやすいような記述にしておきました。trueならばcheckid_setupを意味し、falseならばcheckid_immediateモードを実行します。

認証結果の処理

 OpenID::ConsumerApp::Controller::Login::Handlerモジュールを見てください。前と同様index()メソッドを見ます。

if (my $setup_url =  $csr->user_setup_url) {
     $c->res->redirect($setup_url);
}
elsif (my $vident =  $csr->verified_identity) {
     $c->res->body("Verified URL :  " . $vident->url);
}
elsif ($csr->user_cancel) {
     $c->res->body('Cancel');
}
else {
     Catalyst::Exception->throw('Error : ' . $csr->err);
}
リスト3 OpenID::ConsumerApp::Controller::Login::Handlerのindex()メソッド(抜粋)

 上記はindex()メソッドの一部だけ抜粋しました。IdPからリダイレクトされるケースと、そのタイミングで行うべき処理がここに凝縮されています。

 まず、checkid_immediateモードでopenid.user_setup_urlがIdPから返されるケースでは、再びUser-Agentをその指定URLにリダイレクトさせなければなりません。このURLでEnd UserはIdPからConsumerへ、自分の認証結果をどのように伝えるかに関して聞かれるでしょう。

 verified_identity()メソッドの実行が正常に終了した場合、Net::OpenID::VerifiedIdentityオブジェクトが返されます。このverified_identity()メソッドでdumbモードだった場合は、checkid_authenticationモードも実行してくれます。

 最後のuser_cancelは、check系のモードの場合はid_resというモードでIdPからレスポンスが返ってきますが、例外としてはcheckid_setupモードを実行した場合に、End Userが認証結果の通知をキャンセルした場合、cancelというモードが返ってきます。従って、このcancelモードでのレスポンスがあった場合、user_cancel()メソッドはtrueとなります。

Profile

サイボウズ・ラボ株式会社

山口 徹(やまぐち とおる)

サイボウズ・ラボ株式会社のプログラマー。

バーテンダーからIT業界に転身後、様々なWeb制作を行い、大規模コミュニティサイトの開発・運用を経て、現在は研究開発の日々。Perl使い。

Perlを中心とした開発のノウハウやネタをShibuya Perl Mongersのイベント等で発表するなど講演活動も行う。

個人の開発日記は「Yet Another Hackadelic」、仕事のブログは「log4ZIGOROu



Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       

Security & Trust 記事ランキング

  1. 「SQLite」のゼロデイ脆弱性、GoogleのAIエージェントが見つける AIは脆弱性調査の課題をどう解決したのか?
  2. 増える標的型ランサムウェア被害、現場支援から見えてきた実態と、脆弱性対応が「限界」の理由
  3. 日本人の約半数が「1年前より危険」と考えるオンライン詐欺とは マカフィーがホリデーショッピング詐欺に関して調査
  4. 「このままゼロトラストへ進んでいいの?」と迷う企業やこれから入門する企業も必見、ゼロトラストの本質、始め方/進め方が分かる無料の電子書籍
  5. Google Cloudがサイバーフィジカルシステムのレジリエンスを高める10の指標を解説 最初にすべきことは?
  6. 長続きする高度セキュリティ人材育成の秘訣を「第19回情報危機管理コンテスト」から探る
  7. AIチャットを全社活用している竹中工務店は生成AIの「ブレーキにはならない」インシデント対策を何からどう進めたのか
  8. Microsoftが注意喚起 「クイックアシスト」を悪用した「テクニカルサポート詐欺」の手口、対策とは
  9. 「ランサムウェアに一度感染したら、身代金を払ってもまた攻撃される」のはほぼ確実? ウィズセキュア調査
  10. ランサムウェア攻撃を受けた企業、約6割が「サプライチェーンのパートナー経由で影響を受けた」 OpenText調査
ページトップに戻る