プログラムセキュリティの実装

各リソースにプログラムセキュリティを追加することによって、それらのリソースへのアクセスを詳細に管理できます。サーブレット API に含まれているメソッドを使用すると、サーブレットと JSP に呼び出しを含めて、現在のユーザーと、そのユーザーが与えられたロールに属しているかどうかを判断できます。これによって、実行時に条件付きでコンテンツを作成できます。

メモ:  サーブレットの指定では、サーブレット自体に認証制限を作成しません。認証制限はアプリケーションレベルで指定します。この指定では、サーブレットに適用される認証制限をそのサーブレットが認識できます。

このセクションでは、サーブレットや JSP のコンテンツを条件付きで変更するサーブレット API の使用例を示します。選択したサーブレットのグループに適用できるサーブレットフィルタでも、このセクションで説明するテクニックを使用できます。プログラムセキュリティと宣言セキュリティの組合せによって、コードの再利用が促進され、アプリケーションのメンテナンスが容易になります。フィルタの詳細については、弟 7 章、「フィルタ」を参照してください。

リクエストメソッドの理解

サーブレットの HttpServletRequest オブジェクトのメソッドを使用するか、JSP ページの作成時に request オブジェクトのメソッドを使用して、サーブレットをリクエストしたユーザーの情報を取得します。次の表で、HttpServletRequest オブジェクトで利用できるセキュリティ関連のメソッドを説明します。
メソッド
説明
getAuthType
サーブレットを保護する認証メソッドを返します。可能性の
ある戻り値は、BASIC と FORM です。サーブレットが認証を必要としない場合は、null を返します。
getRemoteUser
現在のユーザー名を文字列で返します。認証されている
ユーザーがいない場合は、null を返します。
isUserInRole
(String role)
現在のユーザーが、与えられた論理的なロール名の一部である場合は、Boolean タイプを true に設定して返します。現在のユーザーが認証されていない場合は、false を返します。
getUserPrincipal
現在のユーザーを表わす java.security.PrincipalString オブジェクトを返します。または、認証されているユーザーがいない
場合は、null を返します。

認証されているユーザーがいない場合、isUserInRole メソッドは false を返します。プログラムセキュリティのためのサーブレット API のメソッドは、ユーザーの認証には使用できません。認証は、resource-constraint 要素を使用してリソースにアクセスを試みることによってユーザーが開始する必要があります。

ロール情報の使用

サーブレットの本文では、次の例に示すように、ユーザーのロールを判別してサーブレットを条件付きで実行できます。

...
public void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws IOException {
  ...
  if(req.isUserInRole("manager")) {
    // manager として処理します。
  }
  if(req.isUserInRole("all")) {
    // 他のすべてのユーザーとして処理します。
  }
...

JSP ページ内では、次の例を使用してページを条件付きで処理できます。

<%
  if(req.isUserInRole("manager")) {
    // manager として処理します。
  }
  if(req.isUserInRole("all")) {
    // 他のすべてのユーザーとして処理します。
  }
%>

移植可能ロールの作成

サーブレット API を使用することにより、アプリケーションでプログラムして使用するロール名から、ユーザーレポジトリに保管されたロール名へのクロスリファレンスを作成できます。このクロスリファレンスは、web.xml 内に作成します。

security-role-ref 要素を使用することにより、サーブレット内にハードコードされたロール名や、サーブレットコンテナによって role-link 要素として使用されるロール名を定義できます。これで、修正や再コンパイルを行わなくても、さまざまなロール名を使用するコンテナにサーブレットをデプロイできるようになります。

たとえば、マネージャのために MGR というロール名を使用するサーブレットコンテナと、manager のロールをチェックするサーブレットを考えます。web.xml 内のサーブレット定義には次のコードが含まれます。

...
<servlet>
  <servlet-name>myServlet</servlet-name>
  <servlet-class>myServlet</servlet-class>
  <security-role-ref>
    <role-name>manager</role-name>
    <role-link>MGR</role-link>
  </security-role-ref>
</servlet>
...

次のコードに示すように、isUserInRole が呼び出されると、サーブレットコンテナはこのクロスリファレンスを実行します。

if (request.isUserInRole("manager")) {
   … // manager 専用のロジックを追加します。
}

サーブレット開発者はロールを表す語句を使用でき、その語句をアプリケーション開発者が指定したロール名にリンクできます。アプリケーション開発者がアプリケーションに関連付けられているロールを修正した場合でも、JSP 開発者は web.xml ファイル内のロールのリンクを変更するだけで済みます。

ロールのリンクによって、サーブレットは、role-name タグで定義されているロールに基づいて常に条件付きで処理を行います。role-link タグを使用して、Web アプリケーションの一部としてこのようなサーブレットを使用することにより、サーブレットのロール定義をアプリケーションの定義に関連付けることができます。