2014年7月21日月曜日

【GAE】初級実装編 シングルサインオン

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

只今、クラウド基盤「Google App Engine(以下、GAE)」の連載しています。

今回はシングルサインオンでログイン機能を作っていきます。

画面レイアウト

ログイン画面は以下のレイアウトにしました。


お馴染み「ユーザID」と「パスワード」を入力する欄がありませんね?

はい。
このシステムでは「シングルサインオン」を使ってログイン機能を実装したいと思います。

シングルサインオン

シングルサインオンとは、「一回のログイン認証によって、複数のシステムへ同時にログイン出来る機能」のことです。

シングルサインオンを使用する場合、ログインIDとパスワードは利用先に丸投げすることになるので、
自社でログインIDとパスワードを保持することはありません。

昨今問題になっている「個人情報流出」のリスクも、自社で持たないことで軽減することが可能なのです。


「何も持たないことが長所」


クラウド時代におけるスマートな姿勢の一つですね。

身の回りでよく使用されている例と言えば……、ちょっと「一般的」と言える程普及はしていないかも。

探せばあるんですけどね。
僕がシングルサインオン界で一番幅を利かせていると思うのは、FaceBookでしょうか。
「このシステムはFaceBookのIDでログイン出来ます」というFaceBookのシングルサインオンが最も良く登場するイメージです。

しかし、「常識」と呼べる程は完全普及していないと思います。


私はこの状況は改善されるべきものであると考えています。

処理効率を考えれば、「全人類が共通で一つのアカウントを持っていて、どのシステムでもそれを使ってログイン出来る」という状況がベストです。
世界的な標準化機構が主導して世界統一アカウントを作るくらいの動きがあって然るべきと考えています。

まあ、色々と難しいハードルがあるみたいで、現状、世界統一アカウントと呼べるものは存在しません。

しかし、世界統一アカウントに準ずる存在と言えるものはあると思います。
それが「Googleアカウント」と「AppleID」です。

AndroidスマホとiPhoneを持っている人はみんなこれらのアカウントを持っているわけですから、
現実のシェアを考えると、この2つが世界統一アカウントに最も近いものだと思います。

現在、私が作っているアプリはGAEのアプリですので、ここは「Googleアカウント」に便乗させて頂こうと思います。

「俺のシステムを使いたいならGoogleアカウントを持って来い!!」というスタイルです。

この辺りはアプリの性質を鑑みての判断になるでしょうね。

「いや、このアプリはGoogleIDを持っていない人も使うものだし……」みたいな懸念があるなら普通にログインIDとパスワードをDBに保有すれば良いです。
(代わりに流出リスクという業を背負うことになりますが)

ただ、GAEはGoogleアカウントを使うことで解禁される機能が存在しますので、
GAEシステムの利用はGoogleアカウント保有者に限定し、持っていない人には新規作成するようガイダンスする、という方向で努力した方が合理的だと思います。

開発

では、自分のGAEアプリの中でGAEにログインする方法を解説します。

まずは現状ログインチェックです。

protected void loginCheck() throws ValidationCheckException {

 UserService userService = UserServiceFactory.getUserService();
 User user = userService.getCurrentUser();

 if (user == null) {
  logger.fine("このユーザはログイン認証を行っていません。");
  throw new ValidationCheckException(ResponseCode.NOT_LOGIN);
 }

};

「UserService」クラスの「getCurrentUser()」の結果がnullだったら未ログイン。
nullでなかったらログイン済みです。

そして、nullだった場合は、Googleのログイン画面に飛ばします。

そこから先はGoogleユーザならお馴染みのログイン画面です。
流石に顔を恥ずかしいのでマスクした画像を載せますが、別に正体を隠さねばならない理由はありません。(;^_^)



ここがポイントです。

自分でログイン画面を作るのではなく、Google画面にワープさせて、ログインさせてから戻ってきて貰う。

これによって、自社でパスワード認証をすることは無いので、自社の責任で流出することは絶対に無いのです。

次に問題となるのは、どうやってGoogle画面にワープさせるか、です。その方法は以下になります。

protected LoginOutUrlJet doResponse() throws Exception {

  LoginOutUrlJet jet = new LoginOutUrlJet();

  UserService userService = UserServiceFactory.getUserService();

  jet.setUrl(userService.createLoginURL("戻ってきて欲しいパス"));

  jet.setResponseCode(ResponseCode.SUCCESS);

  return jet;
 }

「UserService」クラスの「createLoginURL()」メソッドで、Google画面のURLを取得出来ますので、
後はこのURLの先にJavaScript等で強制遷移させれば良いというワケです。

ちなみに、このURLは「ログインさせてから戻ってきて貰う」の機能も内包しているものです。

「userService.createLoginURL("戻ってきて欲しいパス")」

こうすることで、ログイン後に自動的に指定したパスのURLに戻ってきてくれるよう、Google側で制御してくれます。

例えば、ログイン後は常にトップ画面に戻ってきて欲しい場合は、

「jet.setUrl(userService.createLoginURL("/"));」と書けばOKです。

分かり易いですね。

終わりに

今回のシングルサインオンは、開発者に「持たないメリット」を理解する手助けになると思います。

昨今は個人情報保護法など色々とセキュリティ面で厳しい世の中になってきました。
その厳しいセキュリティ水準に耐えられるシステムを作るのは……、ハッキリ言って至難です。

「一応ちゃんとやってるつもりだけど、スーパーハッカーに襲われたら知らんし……」
「っていうか、このシステム、品質ボロボロでセキュリティなんてザルみたいなもんだし……」

こんな有様のシステムも少なく無い現状です。
こういう面倒さ、難しさををGoogleに丸投げ出来るのもGAEのメリットなのです。

引き続き、GAE開発を続けて行きます。

1 件のコメント: