このチュートリアルでは、「JAAS 認証」チュートリアルで開発したプログラムおよびポリシーファイルを拡張して、JAAS 承認コンポーネントの働きを示します。JAAS 承認コンポーネントは、認証された呼び出し側が、そのあとのセキュリティー関連の操作に必要なアクセス制御権 (アクセス権) を保持することを保証します。承認コンポーネントでは、ユーザー認証が完了していることが最初に要求されます。このため、「JAAS 認証」チュートリアルを先にお読みください。
このチュートリアルは、次のセクションで構成されます。
チュートリアルのコードを最初に実行してみる場合は、「承認チュートリアルコードの実行」を先に読んでから、その他のセクションに戻り、学習を続けてください。
JAAS 承認は、セキュリティーポリシーを使用して実行コードに付与するアクセス権を指定する、既存の Java セキュリティーアーキテクチャーを拡張します。これは、Java 2 プラットフォームで導入された、コード中心のアーキテクチャーです。つまり、コードの特性に基づいてアクセス権が付与されます。この特性には、コードが生成された場所、デジタル署名されているかどうか、署名されている場合はだれによって署名されているか、などがあります。具体例としては、「JAAS 認証」チュートリアルで使用される sampleacn.policy ファイルがあります。このファイルには、次が含まれます。
grant codebase "file:./SampleAcn.jar" {
permission javax.security.auth.AuthPermission
"createLoginContext.Sample";
};
これにより、現行ディレクトリの SampleAcn.jar ファイル内のコードに、指定されたアクセス権が付与されます。署名者は指定されていないため、コードが署名されているかどうかは問題となりません。
JAAS 承認は、既存のコード中心のアクセス制御をユーザー中心のアクセス制御で補強します。どのコードが実行されているかだけではなく、どのユーザーが実行しているかに基づいて、アクセス権を付与できます。
アプリケーションが JAAS 認証を使ってユーザーまたはその他のエンティティー (サービスなど) を認証すると、結果としてサブジェクトが生成されます。サブジェクトは、認証されたユーザーを表します。サブジェクトは一連のプリンシパルで構成され、各プリンシパルはそのユーザーの識別情報を表します。さらに、自身をその他のサブジェクトから区別する名前のプリンシパル (「Susan Smith」) や社会保障番号のプリンシパル (「987-65-4321」) などを持つことができます。
ポリシー内で特定のプリンシパルにアクセス権を付与できます。ユーザーの認証後、アプリケーションはサブジェクトと現在のアクセス制御コンテキストを関連付けることができます。そのあと、セキュリティーチェックの対象となる操作 (ローカルファイルアクセスなど) のたびに、Java ランタイムにより、ポリシー内で特定のプリンシパルだけに必要なアクセス権が付与されているかどうかの自動確認が行われます。そして、アクセス制御コンテキストに関連付けられたサブジェクトに指定のプリンシパルが含まれている場合にかぎり、その操作が許可されます。
JAAS 承認を実行する前に、次のようにします。
ポリシーファイルの grant 文に、1 つ以上の Principal フィールドをオプションで含めることができるようになりました。Principal フィールドは、指定されたプリンシパルで表される (指定されたコードを実行する) ユーザーまたはその他のエンティティーが、特定のアクセス権を保持することを表します。
このため、grant 文の基本的な書式は次のようになります
grant <signer(s) field>, <codeBase URL>
<Principal field(s)> {
permission perm_class_name "target_name", "action";
....
permission perm_class_name "target_name", "action";
};
signer、codeBase、Principal の各フィールドはオプションであり、各フィールドの順序は重要ではありません。
Principal フィールドは、次のようになります。
Principal Principal_class "principal_name"
つまり、「Principal」という語 (大文字、小文字は区別されない) に続き、完全修飾の Principal クラス名およびプリンシパル名を指定します。
Principal クラスは、java.security.Principal インタフェースを実装するクラスです。すべての Principal オブジェクトは、getName メソッドの呼び出しによって取得できる関連名を持っています。名前に使用される書式は、Principal 実装によって異なります。
このチュートリアルで使用する、基本的な認証メカニズムにより作成されるサブジェクト内に配置されるプリンシパルのタイプは、SamplePrincipal です。これが、grant 文のプリンシパル指示部の Principal_class で使用されます。SamplePrincipal のユーザー名は「name」の形式になります。このチュートリアルで使用可能なユーザー名は「testUser」のみです。したがって、grant 文の指示部 principal_name では「testUser」を使用します。
単一の grant 文内に複数の Principal フィールドを含めることも可能です。複数の Principal フィールドを指定する場合、現行のアクセス制御コンテキストに関連付けられたサブジェクトにこれらのプリンシパルのすべてが含まれる場合にのみ、grant 文のアクセス権が付与されます。
複数のプリンシパルに同じアクセス権のセットを付与するには、複数の grant 文を作成し、各文にアクセス権のリストといずれかのプリンシパルを指し示す単一の Principal フィールドを含めます。
このチュートリアルのポリシーファイルでは、Principal フィールドに 1 つの grant 文が含まれます。
grant codebase "file:./SampleAction.jar",
Principal sample.principal.SamplePrincipal "testUser" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.io.FilePermission "foo.txt", "read";
};
これは、指定したアクセス権を、SampleAction.jar 内のコードを実行する指定されたプリンシパルに付与することを示します。(注:SamplePrincipal クラスは sample.principal パッケージ内にあります。)
サブジェクトを作成し、現在のアクセス制御コンテキストに関連付けるには、次のようにします。
doAs を呼び出し、認証された Subject と java.security.PrivilegedAction または java.security.PrivilegedExceptionAction を渡します。(PrivilegedAction と PrivilegedExceptionAction の違いについては、「特権ブロックのための API」を参照してください。)doAs メソッドは、提供されたサブジェクトを現在のアクセス制御コンテキストに関連付け、アクションから run メソッドを呼び出します。run メソッド実装には、指定されたサブジェクトとして実行されるすべてのコードが含まれています。このため、アクションは指定されたサブジェクトとして実行されます。
このチュートリアルでも例を示しますが、Subject クラスの static メソッド doAs の代わりに、同じクラスの static メソッド doAsPrivileged が呼び出される場合があります。doAs は、doAsPrivileged に渡されるパラメータのほかに 3 番目のパラメータ AccessControlContext を必要とします。doAsPrivileged は、doAs のように提供された Subject を現在のアクセス制御コンテキストに関連付けるのではなく、提供されたアクセス制御コンテキストまたは空のアクセス制御コンテキスト (渡されたパラメータが null の場合) に関連付けます。これについては、このチュートリアルで例を示します。これらのメソッドの相違点については、『JAAS リファレンスガイド』の「doAs と doAsPrivileged」を参照してください。
このチュートリアルのコードは、4 つのファイルで構成されます。
Subject.doAsPrivileged の呼び出しに必要なコードが追加されている点以外は、「JAAS 認証」チュートリアルの SampleAcn.java アプリケーションファイルとまったく同じです。run メソッドを持っています。SampleLoginModule.java ファイルと SamplePrincipal.java ファイルについては「JAAS 認証」チュートリアルで取り上げているので、ここでは詳しい説明を省略します。その他のソースファイルについては、以降のセクションを参照してください。
SampleAcn と同様に、SampleAzn クラスは LoginContext lc をインスタンス化し、login メソッドを呼び出して認証を実行します。認証に成功した場合は、LoginContext の getSubject メソッドを呼び出すことにより、認証されたサブジェクト (ユーザーを表す SamplePrincipal を含む) を取得します。
Subject mySubject = lc.getSubject();
main メソッドは、サブジェクトに関する情報 (たとえばそのサブジェクトのプリンシパル情報) をユーザーに提供したあと、Subject.doAsPrivileged を呼び出し、次に示すように、認証されたサブジェクト mySubject、PrivilegedAction (SampleAction)、null AccessControlContext を渡します。
SampleAction クラスは、次の方法でインスタンス化されます。
PrivilegedAction action = new SampleAction();
Subject.doAsPrivileged の呼び出しは、次の方法で行われます。
Subject.doAsPrivileged(mySubject, action, null);
doAsPrivileged メソッドは、PrivilegedAction action (SampleAction) の run メソッドを呼び出して、サブジェクト mySubject の代わりの実行と見なされる残りのコードの実行を開始します。
3 番目の AccessControlContext 引数として doAsPrivileged に null を渡すことにより、mySubject が新しい空の AccessControlContext に関連付けられることを示します。その結果、SampleAction の実行時のセキュリティーチェックでは、mySubject として実行される SampleAction コード自体 (またはこのコードによって呼び出されるその他のコード) のアクセス権のみが必要になります。doAsPrivileged の呼び出し側 (および doAsPrivileged が呼び出された時点で実行スタック上に存在していた呼び出し側) は、アクションが実行されている間、アクセス権を必要としません。
SampleAction.java には、SampleAction クラスが含まれます。このクラスは、java.security.PrivilegedAction を実装し、サブジェクト mySubject として実行するすべてのコードを含む run メソッドを持っています。このチュートリアルでは、3 つの操作を実行します。どの操作の場合も、あらかじめ必須アクセス権としてコードを付与しておく必要があります。次を実行します。
java.home システムプロパティーの値を読み取り、出力する。user.home システムプロパティーの値を読み取り、出力する。foo.txt という名前のファイルが存在するかどうかを確認する。次に、コードを示します。
package sample;
import java.io.File;
import java.security.PrivilegedAction;
public class SampleAction implements PrivilegedAction {
public Object run() {
System.out.println("\nYour java.home property value is: "
+ System.getProperty("java.home"));
System.out.println("\nYour user.home property value is: "
+ System.getProperty("user.home"));
File f = new File("foo.txt");
System.out.print("\nfoo.txt does ");
if (!f.exists())
System.out.print("not ");
System.out.println("exist in the current working directory.");
return null;
}
}
このチュートリアルで使用するログイン構成ファイルを、「JAAS 認証」チュートリアルで使用するものとまったく同じにできます。このため、1 つのエントリのみを含む sample_jaas.config を使用できます。
Sample {
sample.module.SampleLoginModule required debug=true;
};
このエントリの名前は「Sample」です。チュートリアルアプリケーション SampleAcn および SampleAzn がこのエントリを参照する際、この名前を使用します。このエントリは、ユーザー認証に使用するログインモジュールが sample.module パッケージ内の SampleLoginModule であること、および認証が成功したと見なされるためにはこの SampleLoginModule が「成功する」必要があることを示します。SampleLoginModule は、ユーザーから提供された名前とパスワードが正しい (それぞれ testUser と testPassword である) 場合にかぎり成功します。
SampleLoginModule は「debug」オプションも定義します (true に設定可能)。このオプションの値を true に設定すると、SampleLoginModule により、認証の進捗に関する追加情報が出力されます。
この承認チュートリアルのアプリケーションは、SampleAzn と SampleAction の 2 つのクラスで構成されます。各クラスのコードにはセキュリティー関連操作が含まれるため、操作を実行するには、ポリシーファイル内に関連するアクセス権を指定する必要があります。
このチュートリアルで使用するログインモジュール (SampleLoginModule) にも、アクセス権を必要とする操作が含まれています。
これらの各クラスが必要とするアクセス権については次に説明します。続いて、完全なポリシーファイルへのリンクを示します。
SampleAzn クラスの main メソッドは、アクセス権の必要な 2 つの操作を実行します。次のとおりです。
doAsPrivileged static メソッドの呼び出し。LoginContext の作成方法は、認証チュートリアルの場合とまったく同じです。このため、「createLoginContext.Sample」をターゲットとする同じ javax.security.auth.AuthPermission アクセス権が必要です。
Subject クラスの doAsPrivileged メソッドを呼び出すには、「doAsPrivileged」をターゲットとする javax.security.auth.AuthPermission が必要です。
SampleAzn クラスが、SampleAzn.jar という名前の JAR ファイルに配置されている場合を考えましょう。ポリシーファイル内の次の grant 文を使って、これらのアクセス権を SampleAzn コードに付与できます。
grant codebase "file:./SampleAzn.jar" {
permission javax.security.auth.AuthPermission
"createLoginContext.Sample";
permission javax.security.auth.AuthPermission "doAsPrivileged";
};
SampleAction コードは、アクセス権の必要な 3 つの操作を実行します。次のとおりです。
foo.txt という名前のファイルが存在するかどうかの確認。これらの操作には、次のアクセス権が必要です。
permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "foo.txt", "read";
これらのアクセス権を SampleAction.class 内のコードに付与する必要があります。このファイルは、SampleAction.jar という名前の JAR ファイル内に配置されます。ただし、この特定の grant 文の場合、アクセス権をコードだけではなく、コードを実行する特定のユーザーにも付与することにより、アクセスを特定のユーザーに限定する方法を示します。
このため、「プリンシパルベースのポリシーファイル文の作成方法」で説明したように、grant 文は次のようになります。
grant codebase "file:./SampleAction.jar",
Principal sample.principal.SamplePrincipal "testUser" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.io.FilePermission "foo.txt", "read";
};
SampleLoginModule コードは、アクセス権の必要な操作を 1 つ実行します。Subject に Principal を追加するには、「modifyPrincipals」をターゲットとする javax.security.auth.AuthPermission が必要です。grant 文は次のようになります。
grant codebase "file:./SampleLM.jar" {
permission javax.security.auth.AuthPermission "modifyPrincipals";
};
完全なポリシーファイルは、sampleazn.policy です。
JAAS 承認チュートリアルコードを実行するには、次の操作を行う必要があります。
sample パッケージ内にある)。
sample.module パッケージ内にある)。
sample.principal パッケージ内にある)。
javac sample/SampleAction.java sample/SampleAzn.java sample/module/SampleLoginModule.java sample/principal/SamplePrincipal.javaコマンド全体を 1 行に入力してください。
SampleAzn.class および MyCallbackHandler.class を含む JAR ファイル SampleAzn.jar を作成します (注: これらのクラスのソースファイルは SampleAzn.java 内にある)。
jar -cvf SampleAzn.jar sample/SampleAzn.class sample/MyCallbackHandler.class
コマンド全体を 1 行に入力してください。
SampleAction.class を含む SampleAction.jar という名前の JAR ファイルを作成します。
jar -cvf SampleAction.jar sample/SampleAction.class
SampleLoginModule.class と SamplePrincipal.class を含む JAR ファイルを作成します。
jar -cvf SampleLM.jar sample/module/SampleLoginModule.class sample/principal/SamplePrincipal.class
SampleAzn アプリケーションを実行します
-classpath 節 (SampleAzn.jar、SampleAction.jar、および SampleLM.jar JAR ファイル内のクラスを検索するため)。-Djava.security.manager。セキュリティーマネージャーのインストールを指定します。-Djava.security.policy==sampleazn.policy。使用するポリシーファイルとして sampleazn.policy を指定します。-Djava.security.auth.login.config==sample_jaas.config。使用するログイン構成ファイルとして sample_jaas.config を指定します。次に、Microsoft Windows および Unix システムの両方で使用可能なすべてのコマンドを示します。classpath 項目の区切りとして、UNIX システムではコロンを使用するのに対し、Windows システムではセミコロンを使用する点だけが異なります。
次に Windows システムの全コマンドを示します。
java -classpath SampleAzn.jar;SampleAction.jar;SampleLM.jar -Djava.security.manager -Djava.security.policy==sampleazn.policy -Djava.security.auth.login.config==sample_jaas.config sample.SampleAzn
次に UNIX システムの全コマンドを示します。
java -classpath SampleAzn.jar:SampleAction.jar:SampleLM.jar -Djava.security.manager -Djava.security.policy==sampleazn.policy -Djava.security.auth.login.config==sample_jaas.config sample.SampleAzn
コマンド全体を 1 行で入力してください。ここでは、読みやすくするために複数行に分けて表示してあります。コマンドが長すぎる場合は、.bat ファイル (Windows) または .sh ファイル (UNIX) に記述します。このファイルを実行することで、コマンドを実行できます。
要求に応じてユーザー名 (「testUser」) とパスワード (「testPassword」) を入力すると、ログイン構成ファイルに指定された SampleLoginModule により、入力された名前とパスワードのチェックが行われます。ログインに成功すると「Authentication succeeded!」というメッセージが、失敗すると「Authentication failed.」というメッセージが表示されます。このあとに、失敗の原因が示されます。
認証が正常に完了すると、プログラム (SampleAction 内) のほかの部分がユーザーに代わって実行されます。このため、ユーザーは適切なアクセス権をあらかじめ保持している必要があります。ポリシーファイル sampleazn.policy により、ユーザーには必要なアクセス権が付与されているため、java.home および user.home システムプロパティーの値、および foo.txt という名前のファイルが現在のディレクトリに存在するかどうかを示す文が表示されます。