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承認を実行する前に、次のようにします。

プリンシパルベースのポリシー・ファイル文の作成方法

ポリシー・ファイルの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を呼び出し、認証されたSubjectjava.security.PrivilegedActionまたはjava.security.PrivilegedExceptionActionを渡します。(PrivilegedActionPrivilegedExceptionActionの相違点については、付録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) SampleActionrunメソッド内のコードの実行が行われます。現行のポリシー内で認証済のユーザーに必要なアクセス権が付与されていることをプリンシパルから判断できる場合、サブジェクトをアクセス制御コンテキストに関連付けることにより、SampleActionrunメソッド内のセキュリティ関連操作(および直接または間接的に呼び出されるすべてのコード)を実行できるようになります。

JaasAzn.javaは、JaasAcn.javaと同様にLoginContext lcをインスタンス化し、loginメソッドを呼び出して認証を実行します。認証に成功した場合は、LoginContextgetSubjectメソッドを呼び出すことにより、認証されたサブジェクト(ユーザーを表すプリンシパルを含む)を取得します。

Subject mySubject = lc.getSubject();

その後、mainメソッドによりSubject.doAsPrivilegedが呼び出され、次に示すように、認証されたサブジェクトmySubjectPrivilegedAction (SampleAction)、null AccessControlContextが渡されます。

SampleActionクラスは、次の方法でインスタンス化されます。

PrivilegedAction action = new SampleAction();

Subject.doAsPrivilegedの呼出しは、次の方法で行われます。

Subject.doAsPrivileged(mySubject, action, null);

doAsPrivilegedメソッドは、PrivilegedAction action (SampleAction)のrunメソッドを呼び出して、サブジェクトmySubjectのかわりの実行と見なされる残りのコードの実行を開始します。

3番目のAccessControlContext引数としてdoAsPrivilegednullを渡すことにより、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がそれを参照するために使用する名前です。このエントリは、ユーザー認証を実行するために使用するLoginModulecom.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. 次のファイルを1つのディレクトリ内に格納します。
  2. jaasazn.policy内のyour_user_name@your_realmを、実際のユーザー名およびレルムで置き換えます。
  3. SampleAction.javaJaasAzn.javaをコンパイルします。
    javac SampleAction.java JaasAzn.java
  4. JaasAzn.classを含むJaasAzn.jarという名前のJARファイルを作成します。
    jar -cvf JaasAzn.jar JaasAzn.class
  5. SampleAction.classを含むSampleAction.jarという名前のJARファイルを作成します。
    jar -cvf SampleAction.jar SampleAction.class
  6. 次を指定して、JaasAznアプリケーションを実行します
    1. 適切な-classpath節(JaasAzn.jarおよびSampleAction.jar JARファイル内のクラスを検索するため)。
    2. -Djava.security.manager。セキュリティ・マネージャのインストールを指定します。

      警告:

      セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。
    3. -Djava.security.krb5.realm=<your_realm> (使用するKerberosレルム)。
    4. -Djava.security.krb5.kdc=<your_kdc> (使用するKerberos KDC)。
    5. -Djava.security.policy=jaasazn.policy。使用するポリシー・ファイルとしてjaasazn.policyを指定します。
    6. -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という名前のファイルが現在のディレクトリに存在するかどうかに関する文が表示されます。