このチュートリアルでは、「JAAS認証」チュートリアルで開発したプログラムおよびポリシー・ファイルを拡張して、JAAS承認コンポーネントを示します。JAAS承認コンポーネントは、認証された呼出し側が、その後のセキュリティ関連の操作に必要なアクセス制御権(アクセス権)を保持することを保証します。 承認コンポーネントでは、ユーザー認証が最初に完了していることを必要とするため、「JAAS認証」チュートリアルを先にお読みください。
このチュートリアルは、次のセクションで構成されます。
チュートリアルのコードを最初に実行してみる場合は、「承認チュートリアル・コードの実行」を先に読んでから、その他のセクションに戻り、学習を続けてください。
JAAS承認は、セキュリティ・ポリシーを使用して実行コードに付与するアクセス権を指定する、既存のJavaセキュリティ・アーキテクチャを拡張します。 これは、Java 2プラットフォームで導入された、コード中心のアーキテクチャです。 つまり、コードの特性に基づいてアクセス権が付与されます。この特性には、コードが生成された場所、デジタル署名されているかどうか、署名されている場合はだれによって署名されているか、などがあります。 この例は、「JAAS認証」チュートリアルで使用されるjaasacn.policyファイルにあります。 このファイルには、次が含まれます。
grant codebase "file:./JaasAcn.jar" {
permission javax.security.auth.AuthPermission
"createLoginContext.JaasSample";
};
これにより、現行ディレクトリのJaasAcn.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実装によって異なります。
このチュートリアルで使用する、Kerberos認証メカニズムにより作成されるサブジェクト内に配置されるプリンシパルのタイプは、javax.security.auth.kerberos.KerberosPrincipalです。これをgrant文のプリンシパルの指定のPrincipal_class部分で使用すべきです。 KerberosPrincipalのユーザー名は、「name@realm」の形式で指定します。 このため、ユーザー名が「mjones」で、レルムが「KRBNT-OPS.ABC.COM」の場合、grant文で使用する完全なprincipal_nameの指定は、「mjones@KRBNT-OPS.ABC.COM」になります。
単一のgrant文内に複数のPrincipalフィールドを含めることも可能です。 複数のPrincipalフィールドを指定する場合、現行のアクセス制御コンテキストに関連付けられたサブジェクトにこれらのプリンシパルのすべてが含まれる場合にのみ、grant文のアクセス権が付与されます。
複数のプリンシパルに同じアクセス権のセットを付与するには、複数のgrant文を作成し、各文にアクセス権のリストといずれかのプリンシパルを指し示す単一のPrincipalフィールドを含めます。
このチュートリアルのポリシー・ファイルでは、Principalフィールドに1つのgrant文が含まれます。
grant codebase "file:./SampleAction.jar",
Principal javax.security.auth.kerberos.KerberosPrincipal
"your_user_name@your_realm" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.io.FilePermission "foo.txt", "read";
};
ここで、「your_user_name@your_realm」には、使用するKerberosユーザー名、「@」、およびレルムを指定します。
これは、指定したアクセス権を、SampleAction.jar内のコードを実行する指定されたプリンシパルに付与することを示します。
サブジェクトを作成し、アクセス制御コンテキストに関連付けるには、次のようにします。
doAsを呼び出し、認証されたSubjectとjava.security.PrivilegedActionまたはjava.security.PrivilegedExceptionActionを渡します。 (PrivilegedActionとPrivilegedExceptionActionの違いについては、「特権ブロックのためのAPI」を参照してください。) doAsメソッドは、提供されたサブジェクトを現在のアクセス制御コンテキストに関連付け、アクションからrunメソッドを呼び出します。 runメソッド実装には、指定されたサブジェクトとして実行されるすべてのコードが含まれています。 このため、アクションは指定されたサブジェクトとして実行されます。
doAsメソッドの代わりに、SubjectクラスのstaticメソッドdoAsPrivilegedを呼び出すことができます。 doAsPrivilegedは、doAsに渡されるパラメータの他に3番目のパラメータAccessControlContextを必要とします。 提供されたサブジェクトを現在のアクセス制御コンテキストに関連付けるdoAsと異なり、doAsPrivilegedは、サブジェクトを提供されたアクセス制御コンテキストに関連付けます。 これらのメソッドの相違点については、『JAASリファレンス・ガイド』の「doAsとdoAsPrivileged」を参照してください。
このチュートリアルのコードは、2つのファイルで構成されます。
Subject.doAsPrivilegedの呼出しに必要なコードが追加されている点以外は、「JAAS認証」チュートリアルのJaasAcn.javaとまったく同じです。runメソッドを持っています。 JaasAzn.javaは、認証終了後のmainメソッドの最後に3つの文が追加されている点を除き、前のチュートリアルで使用したJaasAcn.javaコードとまったく同じです。 追加された3つの文により、(1)認証されたユーザーを表すサブジェクトの、現行のアクセス制御コンテキストへの関連付け、(2) SampleActionのrunメソッド内のコードの実行が行われます。 現行のポリシー内で認証済みのユーザーに必要なアクセス権が付与されていることをプリンシパルから判断できる場合、サブジェクトをアクセス制御コンテキストに関連付けることにより、SampleActionのrunメソッド内のセキュリティ関連操作(および直接または間接的に呼び出されるすべてのコード)を実行できるようになります。
JaasAzn.javaは、JaasAcn.javaと同様にLoginContext lcをインスタンス化し、loginメソッドを呼び出して認証を実行します。 認証に成功した場合は、LoginContextのgetSubjectメソッドを呼び出すことにより、認証されたサブジェクト(ユーザーを表すプリンシパルを含む)を取得します。
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という名前のファイルが存在するかどうかを確認する。次に、コードを示します。
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つのエントリのみを含むjaas.confを使用できます。
JaasSample {
com.sun.security.auth.module.Krb5LoginModule required;
};
このエントリの名前は「JaasSample」で、チュートリアル・アプリケーションJaasAcnおよびJaasAznがそれを参照するために使用する名前です。 このエントリは、ユーザー認証を実行するために使用するログイン・モジュールがcom.sun.security.auth.moduleパッケージ内のKrb5LoginModuleであること、および認証が成功したと見なされるためにはこのKrb5LoginModuleが「成功する」必要があることを示します。 Krb5LoginModuleが成功するのは、ユーザーが入力した名前およびパスワードを使用して、Kerberos KDCへのログインに成功した場合だけです。
この承認チュートリアルには、2つのクラス、JaasAznおよびSampleActionが含まれます。 各クラスのコードにはセキュリティ関連操作が含まれるため、操作を実行するには、ポリシー・ファイル内に関連するアクセス権を指定する必要があります。
JaasAznクラスのmainメソッドは、アクセス権の必要な2つの操作を実行します。 次のとおりです。
doAsPrivileged staticメソッドの呼出し。LoginContextの作成方法は、認証チュートリアルの場合とまったく同じです。このため、「createLoginContext.JaasSample」をターゲットとする同じjavax.security.auth.AuthPermissionアクセス権が必要です。
SubjectクラスのdoAsPrivilegedメソッドを呼び出すには、「doAsPrivileged」をターゲットとするjavax.security.auth.AuthPermissionが必要です。
JaasAznクラスが、JaasAzn.jarという名前のJARファイルに配置されている場合を考えましょう。ポリシー・ファイル内の次のgrant文を使って、これらのアクセス権をJaasAznコードに付与できます。
grant codebase "file:./JaasAzn.jar" {
permission javax.security.auth.AuthPermission
"createLoginContext.JaasSample";
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 javax.security.auth.kerberos.KerberosPrincipal
"your_user_name@your_realm" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
permission java.io.FilePermission "foo.txt", "read";
};
「your_user_name@your_realm」には、使用するKerberosユーザー名、「@」、およびレルムを指定します。 たとえば、ユーザー名が「mjones」、レルムが「KRBNT-OPERATIONS.ABC.COM」の場合、"mjones@KRBNT-OPERATIONS.ABC.COM" (引用符も付ける)を指定します。
完全なポリシー・ファイルは、jaasazn.policyです。
JAAS承認チュートリアル・コードを実行するには、次の操作を行う必要があります。
jaasazn.policy内の「your_user_name@your_realm」を、実際のユーザー名およびレルムで置き換えます。SampleAction.javaとJaasAzn.javaをコンパイルします。
javac SampleAction.java JaasAzn.java
JaasAzn.classを含むJaasAzn.jarという名前のJARファイルを作成します。
jar -cvf JaasAzn.jar JaasAzn.class
SampleAction.classを含むSampleAction.jarという名前のJARファイルを作成します。
jar -cvf SampleAction.jar SampleAction.class
JaasAznアプリケーションを実行します
-classpath節(JaasAzn.jarおよびSampleAction.jar JARファイル内のクラスを検索するため)。-Djava.security.manager。セキュリティ・マネージャのインストールを指定します。-Djava.security.krb5.realm=<your_realm> (使用するKerberosレルム)。-Djava.security.krb5.kdc=<your_kdc> (使用するKerberos KDC)。-Djava.security.policy=jaasazn.policy。使用するポリシー・ファイルとしてjaasazn.policyを指定します。-Djava.security.auth.login.config=jaas.conf。使用するログイン構成ファイルとしてjaas.confを指定します。次に、Microsoft WindowsおよびSolaris、LinuxおよびMac OS Xシステムで使用するすべてのコマンドを示します。 classpath項目の区切りとして、Solaris、LinuxおよびMac OS Xではコロンを使用するのに対し、Windowsシステムではセミコロンを使用する点のみが異なります。 <your_realm>をKerberosレルムと、<your_kdc>をKerberos KDCと置き換えてください。
次にWindowsシステムの全コマンドを示します。
java -classpath JaasAzn.jar;SampleAction.jar -Djava.security.manager -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.policy=jaasazn.policy -Djava.security.auth.login.config=jaas.conf JaasAzn
次に、Solaris、LinuxおよびMac OS Xシステムのすべてのコマンドを示します。
java -classpath JaasAzn.jar:SampleAction.jar -Djava.security.manager -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.policy=jaasazn.policy -Djava.security.auth.login.config=jaas.conf JaasAzn
コマンド全体を1行で入力してください。 ここでは、読みやすくするために複数行に分けて表示してあります。 システムでコマンドが長すぎる場合は、.batファイル(Windowsの場合)または.shファイル(Solaris、LinuxおよびMac OS Xの場合)にそれを入れる必要がある場合があります。このファイルを実行することで、コマンドを実行できます。
Kerberosユーザー名とパスワードの入力が求められます。ログイン構成ファイルで指定された、基盤となるKerberos認証メカニズムにより、Kerberosへのログインが行われます。 ログインが成功すると「Authentication succeeded!」というメッセージが、失敗すると「Authentication Failed」というメッセージが表示されます。
ログイン時のトラブルシューティングについては、「トラブルシューティング」を参照してください。
認証が正常に完了すると、プログラム(SampleAction内)の他の部分がユーザーに代わって実行されます。このため、ユーザーは適切なアクセス権をあらかじめ保持している必要があります。 ポリシー・ファイルjaasazn.policyにより、ユーザーには必要なアクセス権が付与されているため、java.homeおよびuser.homeシステム・プロパティの値、およびfoo.txtという名前のファイルが現在のディレクトリに存在するかどうかに関する文が表示されます。