Perlでそこそこ簡単にOpenID ConnectのOP/RPを動かす

こんにちは, ritouです.
天気悪いので前回の続きのエントリ書いちゃいます.
PerlのOpenID Connect用ライブラリOIDC::Liteをざっくり紹介 - r-weblife

前回の紹介したOIDC::Liteを使って, OpenID Connectの動作を確認できるサンプルOP/RPを作ってみましたという話です.

何を作ったのか

サンプルOP/RPはOIDC::Liteを用いたPerlアプリケーションです.
RP側(OAuthでいうところのClient)の動作だけに興味があったり, OP側(OAuthでいうところのServer)のしくみだけ知りたい方もいるかもしれないのであえて別々にしましたが, 激しく一緒でよかったなと思っています.

これで何ができるか

サンプルRP

サンプルRPは, サンプルOPとGoogleに対してOpenID Connectのリクエストを送り, ユーザーの属性情報を取得するまでの処理を実装しています.

サンプルOP

サンプルOPはOpenID ConnectのOPとしての機能を提供します.
サンプルRPのclient_id, client_secretを最初から保持しているため, サンプルRPを立ち上げると比較的簡単に利用できますが, Web上で手動でRPを登録することで任意のRPから利用可能です.

ただし, ユーザー認証やRP開発者の管理などの機能はつけていないので, クローズな環境で立ち上げてフローを確認したりライブラリの利用方法を調べるために使う感じですね.

動かすために何が必要か

Perlの環境が必要です. WindowsユーザーでもVagrant + xbuildあたりでわりと少ない手順で構築できるでしょう.
それぞれのwikiにも書いていますが, "carton install"で依存モジュールを入れてplackupするだけ, 必要ならばconfig以下を修正という感じです.

動かすとどんな感じになるか

VMの中で次のような状態でOP/RP両方を立ち上げて動かしたときのスクリーンショットを載せておきます.

上記のとおり立ち上げた場合はconfig以下の設定変更不要です.
こちらのシーケンスに沿って動作を見ていきましょう.
@ITの記事"「OpenID Connect」を理解する"中のシーケンス図

Authorization Request/Response

まずはサンプルRPにアクセスします.

今回はOIDC::Lite::Demo::Serverのほうを選択し, 認可フローへのリンクをクリックすると, サンプルOPにリダイレクトします.

サンプルOPのAuthorization Endpointでは, 下記の情報を表示します.

  • 認可リクエストが有効であるかの判定結果 : validになっているはず・・・
  • 要求されているscopeとAccept/Denyのボタン

ちなみに, URLを書き換えて不正なリクエストにすると, どのパラメータが不正かなどの情報が表示されます.

さらに, デバッグ目的として, 下記についても表示します.

  • Authorization Request : どんなリクエストが送られたのか

  • Client Information : どんなRPがリクエストを送ってきたのか

  • Requested Claims : どんな属性情報が渡されるのか. UserInfo Endpointで渡されるダミーユーザーの属性情報一覧

ユーザー認証機能について, 現状は「ダミーユーザーがログインしている状態」のような扱いにしています. そのため, max_ageという「この秒数以内に認証したユーザーに限る」みたいなリクエストパラメータには対応していません. このあたりは今後対応予定です.

ユーザーがAccept/Denyした時には, すぐにリダイレクトさせずに認可レスポンスの内容を表示します.

サンプルRPではresponse_type=codeなのでレスポンスにはクエリパラメータのみがついていますが, response_type=code id_tokenなどにしてみるとフラグメントに値が入ります.

一回表示することで, どんなレスポンスが返されるのかがわかりやすかったり 「RP実際のサーバとして立ち上げず手動でAuthorization RequestのURLを組み立ててブラウザに貼り付け, レスポンスからcodeパラメータの部分をコピペしてcurlAccess Token取りに行く」みたいなこともやりやすいと思います.
リンクをクリックすると表示されているURLでサンプルRPに戻ります.

サンプルRPでは次の内容を表示します.

  • Token EndpointからAccess Tokenなどを取得するリクエスト/レスポンスの内容

  • JSON Web Signature形式のID Tokenの内容
  • UserInfo Endpointへのリクエスト/レスポンスの内容

現在はサンプルRPがresponse_type=codeのみを実装していますが, それ以外については今後対応予定です.

localhost以外で動かしたい場合

ホスト名 or IPアドレス + ポート番号が異なる環境で立ち上げた場合は, config/development.plの一部を書き換える必要があります.

サンプルOP側の設定変更箇所はこんな感じです.

         }
     ],
     'SampleClient' => {
-        'redirect_uri' => q{http://localhost:5000/sample/callback},
+        'redirect_uri' => q{http://demo-client.openidconnect.info/sample/callback},
     },
     'OIDC' => {
         'id_token' => {

サンプルRP側もredirect_uriとエンドポイントの部分を変更します.

         'Sample' => {
-            'authorization_endpoint' => 'http://localhost:5001/authorize',
-            'token_endpoint' => 'http://localhost:5001/token',
-            'userinfo_endpoint' => 'http://localhost:5001/userinfo',
+            'authorization_endpoint' => 'http://demo-server.openidconnect.info/authorize',
+            'token_endpoint' => 'http://demo-server.openidconnect.info/token',
+            'userinfo_endpoint' => 'http://demo-server.openidconnect.info/userinfo',
             'client_id' => q{sample_client_id},
             'client_secret' => q{sample_client_secret},
-            'redirect_uri' => q{http://localhost:5000/sample/callback},
+            'redirect_uri' => q{http://demo-client.openidconnect.info/sample/callback},
             'scope' => q{openid email profile phone address},
         },
     },

まとめ

OIDC::Liteを使ったサンプルOP/RPについて紹介しました.
OP/RPのアプリケーションの雛形というよりは, OpenID Connectのフローを理解するためのツールとして作った感じです.

OpenID Connectはだいぶ仕様も固まってきてるので, Perl以外の言語でもこのように簡単に立ち上げられるサンプルOP/RPのニーズはあると思っています.
20日にエンプラ向けのID&ITっていうイベントの中で, RPを実装してみようって言うハンズオンが行われます.

クラウド事業者(主にSaaS事業者)向けにOpenID ConnectのRP(Relying Party)の実装を行うHands-on形式の講習会を開催します.

1. OpenID Connect 技術解説

2. 各クラウドサービスにOpenID Connectを実装するための設計の実習

3. OAuth2 またはJWTライブラリを利用したOpenID Connectの実装

クラウド事業者の実装に関する個別に対して, OIDFJのエバンジェリスト(@nov, @lef, @kura_lab)が設計実習, 実装時, ラウンドテーブル形式で回答します.
※参加される方は各自, 実装実習に利用するPC(事前にご連絡する開発環境設定済み)をご持参いただきます.

http://nosurrender.jp/idit2013/handson.html

コンシューマ向けではY!やGoogle, エンプラ向けではPing Federateなど, OpenID Connectに対応しているOPが出てきています.
そういうところにつないでみるのも良いのですが, 開発以前にRPの登録云々でけっこう手間がかかったりするので, ローカル環境でOPを動かせられればそれはそれで便利かなと思っています.

今後の予定

せっかくなので, このあたりも今後取り上げたいと思います.

  • サンプルOPに手動でRPを登録して動作確認する方法
  • サンプルRPからGoogleOpenID ConnectのOP機能を利用する方法

ではまた!