はじめに
この連載では、「GlassFish」という製品を利用して、Java言語に親しんでもらうことを目的としています。第7回目の今回は、入門編の最終回として、ユーザーを識別する認証機能の実装方法を説明していきます。
対象読者
- Javaでなにかしらのアプリケーションを作成したことのある方
- Javaの変数の宣言や、if文・for文・while文の制御文など簡単な文法を知っており、アプリケーションを作成したことのある方
オブジェクト指向プログラミングができなくとも構いません。徐々に学んでいければと考えています。また、学びやすいWebアプリケーションをサンプルとするので、Webアプリケーションとは違った分野を勉強したい方には当連載は向いていません。
本稿で想定する主要技術のバージョン
Java EE 5を使用するため、主な技術要素のバージョンは以下の通りです。EJBに関しては応用編で扱う予定です。
- Servlet:2.5
- JSP:2.1
- JSTL:1.2
- JTA:1.1
- EJB:3.0(応用編)
芋焼酎酒店に認証機能を実現する
第6回で買い物かごを実装しましたが、複数のユーザーが使える仕組みにはなっていませんでした。ユーザーを識別するには認証機能が必要です。GlassFish組み込みのJDBCレルムを使って認証機能を実現し、複数のユーザーが利用できるようにします。
そもそも認証とは何か
認証(authentication)とはそのシステムに入れるかどうかを判定することを指します。つまり、システムを利用する正当なユーザーであると確認することを認証といいます。簡単に言えば「本人確認」のことです。認可(authorization)と区別しなければなりません。認可とはシステムに入った後、特定の機能が使用できるかどうか判定することを指します。会社の例で言うと、一般社員が閲覧できるページ、課長以上が閲覧できるページ、役員以上が閲覧できるページなどと、役割(role)によって制限がかかっていることがあります。このように役割により特定のページを見ることができるか(つまり、そのページの機能を使用できるか)を判定することを認可と言います。
今回は非常に簡単なサンプルアプリケーションのため、認可については言及しません。応用編で、認証・認可を含めた包括的なセキュアなシステムの構築方法を紹介できればと考えています(※補足)。
authenticationはほとんど認証と訳されていますが、authorizationは認可、承認、権限付与などと呼ばれており、混乱している状態です。当連載では「認可」と呼ぶことにします。
セキュアなシステムと認証・認可
認証・認可さえしっかり実現できていればセキュアなシステムと言えるのかという疑問が残るはずです。当然「否」です。例えば、認証をユーザーIDとパスワードを使う一般的に見られる方式で行う場合、親しいからという安心感から家族や友人にパスワードを教えたとします。これだけでシステムは大変危険に晒されてしまいます。実体験で言うと、友人のマンションではマンションに入るのに鍵がない場合、暗証番号を入力すれば入れるようになっていました。親が子供に教え、子供が友達に教えると暗証番号はあっという間に近所に知られてしまい、マンションは見知らぬ人が出入りするようになり(これが原因か断定はできませんが)空き巣に入られるという最悪な結果となりました。パスワードでの管理とは所詮こんなものであるということを肝に銘じておかなくてはなりません。
認証・認可はシステムをセキュアにするために最低限行うべきだと認識することが最初の一歩です。従って、当連載のサンプルアプリケーションを元にネットショップを作ったとしても、安全である保証はできません。冒頭で記述したように「複数のユーザーを識別するための仕組み」として認証機能を実現します。
セキュアなシステムの補足
セキュアなシステムを構築するには、ネットワーク、運用体制など広範囲な配慮が必要になります。セキュアなシステムの鍵となる技術要素は暗号化技術ですが、一般的に用いられている公開鍵暗号の場合でも、鍵の管理など厳しいルール作りが必要になるということを覚えておいてください。
言葉の定義
「Administration Guide」のP104から認証・認可の場合使用される、ユーザー、グループ、ロール、レルムという言葉を整理します。
ユーザー
エンタープライズサーバによってあらかじめ定義された個人やアプリケーションを指します。日本語にすると分かりづらいですが、Administration Guideでは「individual」という言葉が使用されています。「個」という意味で「1つ」ということを表します。従って個人や1つに特定可能なアプリケーションと捉えるべきです。
また、ユーザーを複数人で使用している例もよく見かけますが、重要な情報にアクセスする場合、複数人に割り当てたユーザーは使用すべきではありません。あくまでも個人に割り当てたユーザーでの認証が必要です。認証・認可だけではシステムはセキュアではないと言いましたが、重要なリソースにアクセスする場合、ログを残すことにより誰がアクセスしたのか特定できなければなりません。このような場合、1つのユーザーを複数人で使用すると特定が困難になります。また、認証されたユーザーを「principal」、ユーザーを「subject」として区別する場合もあります。
グループ
グループもエンタープライズサーバによってあらかじめ定義されている必要があります。グループは共通の特性により分類されるユーザーの集合を指します。
ロール
ロールとはユーザーがアクセスでき、処理できるアプリケーションやアプリケーションの部分を定義するものです。ロールとグループの区別は難しいところですが、グループはユーザーの集合です。しかし、sun-web.xmlを見る限り、ロールを直接ユーザーに割り当てることはなく、ロールはグループに割り当てられます。要するにグループは大量のユーザーが存在する場合を想定して設けられているようです。Tomcatユーザーには少し違和感があるところかもしれません。
レルム
レルムと聞くと身構えてしまいますが、簡単に言えば、ユーザーやグループの情報を格納したリポジトリのことです。レルムは「セキュリティ・ポリシー・ドメイン」とか「セキュリティ・ドメイン」などとも呼ばれます。今回はJDBCレルムのみ紹介しますが、GlassFishにはその他に、Adminレルム、Fileレルム、Certificateレルム、LDAPレルム、Solarisレルム、Customレルムがあります。