JAAS承認
このチュートリアルでは、「JAAS認証」チュートリアルで開発したプログラムおよびポリシー・ファイルを拡張して、JAAS承認コンポーネントを示します。JAAS承認コンポーネントは、認証された呼出し側が、その後のセキュリティ関連の操作に必要なアクセス制御権(アクセス権)を保持することを保証します。承認コンポーネントでは、ユーザー認証が最初に完了していることを必要とするため、「JAAS認証」チュートリアルを先にお読みください。
このチュートリアルは、次のセクションで構成されます。
チュートリアルのコードを最初に実行してみる場合は、「承認チュートリアル・コードの実行」を先に読んでから、その他のセクションに戻り、学習を続けてください。
JAAS承認とは
JAAS承認は、セキュリティ・ポリシーを使用して実行コードに付与するアクセス権を指定する、既存のJavaセキュリティ・アーキテクチャを拡張します(デフォルトのPolicyの実装とポリシー・ファイルの構文を参照)。これは、コード中心のアーキテクチャです。つまり、コードの特性に基づいてアクセス権が付与されます。この特性には、コードが生成された場所、デジタル署名されているかどうか、署名されている場合はだれによって署名されているか、などがあります。この例は、「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承認の実行手順
JAAS承認を実行する前に、次のようにします。
- ユーザーを認証する必要があります(「JAAS認証」チュートリアルを参照)。
- セキュリティ・ポリシー内にプリンシパルベースのエントリを構成する必要があります。プリンシパルベースのポリシー・ファイル文の作成方法を参照してください。
- 認証の結果生成されたサブジェクトと現在のアクセス制御コンテキストを関連付ける必要があります。サブジェクトのアクセス制御コンテキストへの関連付けを参照してください。
プリンシパルベースのポリシー・ファイル文の作成方法
ポリシー・ファイルのgrant
文に、1つ以上のPrincipalフィールドをオプションで含めることができるようになりました(デフォルトのPolicyの実装とポリシー・ファイルの構文を参照)。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
内のコードを実行する指定されたプリンシパルに付与することを示します。
サブジェクトのアクセス制御コンテキストへの関連付け
サブジェクトを作成し、アクセス制御コンテキストに関連付けるには、次のようにします。
- 最初にユーザーを認証する必要があります(「JAAS認証」を参照)。
- Subjectクラスのstaticメソッド
doAs
を呼び出し、認証されたSubjectとjava.security.PrivilegedActionまたはjava.security.PrivilegedExceptionActionを渡します。(PrivilegedActionとPrivilegedExceptionActionの相違点については、付録A: 特権ブロックのためのAPIを参照してください。)doAs
メソッドは、提供されたサブジェクトを現在のアクセス制御コンテキストに関連付け、アクションからrun
メソッドを呼び出します。run
メソッド実装には、指定されたサブジェクトとして実行されるすべてのコードが含まれています。このため、アクションは指定されたサブジェクトとして実行されます。doAs
メソッドのかわりに、SubjectクラスのstaticメソッドdoAsPrivileged
を呼び出すことができます。doAsPrivileged
は、doAs
に渡されるパラメータの他に3番目のパラメータAccessControlContextを必要とします。提供されたサブジェクトを現在のアクセス制御コンテキストに関連付けるdoAs
と異なり、doAsPrivileged
は、サブジェクトを提供されたアクセス制御コンテキストに関連付けます。これらのメソッドの相違点については、『JAASリファレンス・ガイド』のdoAsとdoAsPrivilegedを参照してください。
承認チュートリアル・コード
このチュートリアルのコードは、2つのファイルで構成されます。
JaasAzn.java
は、Subject.doAsPrivileged
の呼出しに必要なコードが追加されている点以外は、JAAS認証チュートリアルのJaasAcn.java
とまったく同じです。SampleAction.java
には、SampleActionクラスが含まれます。このクラスは、PrivilegedActionを実装し、プリンシパルベースの認証チェックで実行するすべてのコードを含むrun
メソッドを持っています。
JaasAzn.java
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
には、SampleActionクラスが含まれます。このクラスは、java.security.PrivilegedAction
を実装し、サブジェクトmySubject
として実行するすべてのコードを含むrun
メソッドを持ちます。このチュートリアルでは、3つの操作を実行します。それぞれ、コードに必要なアクセス権を付与しないかぎり、実行できません。次を実行します。
java.home
システム・プロパティの値を読み取り、出力する。user.home
システム・プロパティの値を読み取り、出力する。- 現行のディレクトリに
foo.txt
という名前のファイルが存在するかどうかを確認する。
ログイン構成ファイル
このチュートリアルで使用するログイン構成ファイルを、「JAAS認証」チュートリアルで使用するものとまったく同じにできます。このため、1つのエントリのみを含むjaas.confを使用できます。
JaasSample {
com.sun.security.auth.module.Krb5LoginModule required;
};
このエントリの名前は「JaasSample」で、チュートリアル・アプリケーションJaasAcn
およびJaasAzn
がそれを参照するために使用する名前です。このエントリは、ユーザー認証を実行するために使用するLoginModuleがcom.sun.security.auth.module
パッケージ内のKrb5LoginModuleであること、および認証が成功したと見なされるためにはこのKrb5LoginModuleが「成功する」必要があることを示します。Krb5LoginModuleが成功するのは、ユーザーが入力した名前およびパスワードを使用して、Kerberos KDCへのログインに成功した場合だけです。
ポリシー・ファイル
この承認チュートリアルには、2つのクラス、JaasAzn
およびSampleAction
が含まれます。各クラスのコードにはセキュリティ関連操作が含まれるため、操作を実行するには、ポリシー・ファイル内に関連するアクセス権を指定する必要があります。
JaasAznに必要なアクセス権
JaasAzn
クラスのmainメソッドは、アクセス権の必要な2つの操作を実行します。次を実行します
- LoginContextの作成。
- Subjectクラスの
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に必要なアクセス権
SampleAction
コードは、アクセス権の必要な3つの操作を実行します。次を実行します
java.home
システム・プロパティの値の読取り。user.home
システム・プロパティの値の読取り。- 現行のディレクトリに
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
を指定します。
承認チュートリアル・コードの実行
JAAS承認チュートリアル・コードを実行するには、次の操作を行う必要があります。
- 次のファイルを1つのディレクトリ内に格納します。
JaasAzn.java
ソース・ファイル。SampleAction.java
ソース・ファイル。jaas.conf
ログイン構成ファイル。jaasazn.policy
ポリシー・ファイル。
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
。セキュリティ・マネージャのインストールを指定します。警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。-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
を指定します。
ノート:
java.security.auth.login.config
システム・プロパティで、(等号を2つ(==
)ではなく)等号を1つ(=
)使用している場合、このシステム・プロパティおよびjava.security
ファイルの両方で指定された構成が使用されます。次に、Windows、LinuxおよびmacOSで使用する完全なコマンドを示します。classpath項目の区切りとして、LinuxおよびmacOSではコロンを使用するのに対し、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
次に、LinuxおよびmacOSの全コマンドを示します。
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ファイル(LinuxおよびmacOSの場合)に記述し、そのファイルを実行して、コマンドを実行する必要がある場合があります。
Kerberosユーザー名とパスワードの入力が求められます。ログイン構成ファイルで指定された、基盤となるKerberos認証メカニズムにより、Kerberosへのログインが行われます。ログインが成功すると「Authentication succeeded!」というメッセージが、失敗すると「Authentication Failed」というメッセージが表示されます。
ログイン時のトラブルシューティングについては、「トラブルシューティング」を参照してください。
認証が正常に完了すると、プログラム(
SampleAction
内)の他の部分がユーザーに代わって実行されます。このため、ユーザーは適切なアクセス権をあらかじめ保持している必要があります。ポリシー・ファイルjaasazn.policy
により、ユーザーには必要なアクセス権が付与されているため、java.home
およびuser.home
システム・プロパティの値、およびfoo.txt
という名前のファイルが現在のディレクトリに存在するかどうかに関する文が表示されます。 - 適切な