IdPでのログインと認証の関係を見てみる
PHP-OpenIDのサンプルには、簡単なログインシステムがついていました。しかし、実際にIdPを公開する際には、それぞれのサービスで持っているログインシステムを利用する必要があります。
例えばlivedoorならlivedoor ID、はてなならはてなのIDをOpenIDとして利用できる仕組みを提供しているように、あなたの提供するサービスのIDを使うことになるわけです。
Consumerからの認証の要求があると、IdPへアクセスがあった際に、指定されたIdentifier URLと現在ログイン中のIDを比較します。同じユーザIDからのアクセスだった場合、認証を行ってもいいのかをエンドユーザに確認し、認証プロセスを進めます。もしログイン状態でなければ、ログインプロセスも実行します。
このときIdentifier URLがログイン中のユーザのものではなかった場合、認証は失敗します。この処理は、各サービスのログインのシステムなどと接続するように作り込んでいかなければなりません。
また、一度認証したtrust_rootの情報を記録しておき、次回からは確認なしで認証を行う仕組みも同様です。サンプルでも、保存したtrust_rootの一覧を表示したり、不要な情報を削除したり、といった機能を提供しています。これと同様に、ユーザごとに認証状態を保存するための仕組みを用意し、さらにそれを管理する画面などが必要となるでしょう。
図3:ログインシステムで作成が必要な箇所
(画像をクリックすると別ウィンドウに拡大図を表示します)
処理を組み込むのはaction_default関数の中となります。getLoggedInUser関数によるログインチェックは、サービスのログイン状態のチェックをする関数に変える必要があるでしょう。また、承認済みのtrust_rootかどうかをチェックするisTrusted関数は、そのユーザごとの情報を取得するような仕組みに変えなければなりません。
ログイン画面を表示するlogin_renderは、そのサービスのログイン画面を使うように変えるべきでしょう(リダイレクトが必要になるかもしれません)。そしてログインが完了した後で、「認証を許可するか」のWebページに進めばいいわけです。
もちろん、ログイン画面に遷移する際には、エンドユーザーから渡された、openid.assoc_typeやopenid.return_toといったOpenIDに関するパラメータをきちんと引き継ぐ必要があります。サンプルでは、session.phpで定義されたgetRequestInfo、setRequestInfoという関数を利用して、それらのデータを引き回しています。
さらにサンプルではgetAction関数を使って処理を分岐していますが、これはログイン/ログアウト/承認済みのURLの一覧などを表示するページと実際の承認用のURLが同じserver.phpによって提供されているためです。
実際には、おそらくログイン関係のページは別ページとして用意するでしょう。このため、本サイトに実装する場合にはgetAction関数によるアクションの分岐は必要ありません。serverのURLが提供するのは、IdPのサーバ機能だけにした方がよいでしょう。
また、IdPを提供する場合は、Identifier URLも同時に提供するのが普通です。Identifier URLはブログサービスならブログのURLを利用することが一般的ですが、専用のURLを用意するケースもあります。
なお、PHP-OpenID 2.XのIdPのサンプルは、冒頭で述べたように、OpenID 2.0を利用していることや、ユーザのログインにパスワードが必要なくなっていること、Identifier URLを自動的に生成する機能があることをのぞけば、使い方や仕組み自体は1.X系のサンプルとほぼ同じです。1.X系のサンプルを理解していれば、こちらも簡単に利用できるでしょう。
次回は、最終回ということで、これまでの事をふまえ、OpenIDの実装方法をより詳しく解説します。