このチュートリアルでは、「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
メソッド実装には、指定されたサブジェクトとして実行されるすべてのコードが含まれています。このため、アクションは指定されたサブジェクトとして実行されます。
このチュートリアルで実行するように、doAs
メソッドの代わりに、SubjectクラスのdoAsPrivileged
staticメソッドを呼び出すことができます。doAsPrivileged
は、doAs
に渡されるパラメータの他に3番目のパラメータAccessControlContextを必要とします。doAsPrivileged
は、指定されたSubjectを現在のアクセス制御コンテキストに関連付ける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およびSolaris、LinuxおよびMac OS Xシステムで使用するすべてのコマンドを示します。classpath項目の区切りとして、Solaris、LinuxおよびMac OS Xシステムではコロンを使用するのに対し、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
次に、Solaris、LinuxおよびMac OS Xシステムのすべてのコマンドを示します。
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ファイル(Solaris、LinuxおよびMac OS Xの場合)にそれを入れる必要がある場合があります。このファイルを実行することで、コマンドを実行できます。
ユーザー名とパスワードの入力が求められ(「testUser」と「testPassword」を使用)、ログイン構成ファイルに指定されたSampleLoginModuleにより、名前とパスワードがチェックされます。ログインが成功すると「Authentication succeeded!」というメッセージが表示され、失敗すると「Authentication failed:」の後に失敗の理由が続くメッセージが表示されます。
認証が正常に完了すると、プログラム(SampleAction
内)の他の部分がユーザーに代わって実行されます。このため、ユーザーは適切なアクセス権をあらかじめ保持している必要があります。ポリシー・ファイルsampleazn.policy
により、必要なアクセス権が付与されているため、java.home
およびuser.home
システム・プロパティの値、およびfoo.txt
という名前のファイルが現在のディレクトリに存在するかどうかに関する文が表示されます。