JAAS承認チュートリアル



このチュートリアルでは、「JAAS認証」チュートリアルで開発したプログラムおよびポリシー・ファイルを拡張して、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承認の実行手順

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パッケージ内にあります。)

サブジェクトのアクセス制御コンテキストへの関連付け

サブジェクトを作成し、現在のアクセス制御コンテキストに関連付けるには、次のようにします。

承認チュートリアル・コード

このチュートリアルのコードは、4つのファイルで構成されます。

SampleLoginModule.javaファイルとSamplePrincipal.javaファイルについては「JAAS認証」チュートリアルで取り上げているので、ここでは詳しい説明を省略します。その他のソース・ファイルについては、以降のセクションを参照してください。

SampleAzn.java

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引数としてdoAsPrivilegednullを渡すことにより、mySubjectが新しい空のAccessControlContextに関連付けられることを示します。その結果、SampleActionの実行時のセキュリティ・チェックでは、mySubjectとして実行されるSampleActionコード自体(またはこのコードによって呼び出されるその他のコード)のアクセス権のみが必要になります。doAsPrivilegedの呼出し側(およびdoAsPrivilegedが呼び出された時点で実行スタック上に存在していた呼出し側)は、アクションが実行されている間、アクセス権を必要としません。

SampleAction.java

SampleAction.javaには、SampleActionクラスが含まれます。このクラスは、java.security.PrivilegedActionを実装し、サブジェクトmySubjectとして実行するすべてのコードを含むrunメソッドを持ちます。このチュートリアルでは、3つの操作を実行します。それぞれ、コードに必要なアクセス権を付与しないかぎり、実行できません。次を実行します。

次に、コードを示します。

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により、認証の進捗に関する追加情報が出力されます。

ポリシー・ファイル

この承認チュートリアルのアプリケーションは、SampleAznSampleActionの2つのクラスで構成されます。各クラスのコードにはセキュリティ関連操作が含まれるため、操作を実行するには、ポリシー・ファイル内に関連するアクセス権を指定する必要があります。

このチュートリアルで使用するログイン・モジュール(SampleLoginModule)にも、アクセス権を必要とする操作が含まれています。

これらの各クラスが必要とするアクセス権については次に説明します。続いて、完全なポリシー・ファイルへのリンクを示します。

SampleAznに必要なアクセス権

SampleAznクラスのmainメソッドは、アクセス権の必要な2つの操作を実行します。次のとおりです。

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に必要なアクセス権

SampleActionコードは、アクセス権の必要な3つの操作を実行します。次のとおりです。

これらの操作には、次のアクセス権が必要です。

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に必要なアクセス権

SampleLoginModuleコードは、アクセス権の必要な操作を1つ実行します。SubjectにPrincipalを追加するには、「modifyPrincipals」をターゲットとするjavax.security.auth.AuthPermissionが必要です。grant文は次のようになります。

grant codebase "file:./SampleLM.jar" {
    permission javax.security.auth.AuthPermission "modifyPrincipals";
};

完全なポリシー・ファイル

完全なポリシー・ファイルは、sampleazn.policyです。

承認チュートリアル・コードの実行

JAAS承認チュートリアル・コードを実行するには、次の操作を行う必要があります。

  1. 次のファイルを1つのディレクトリ内に格納します。
  2. 最上位ディレクトリの下に「sample」という名前のサブディレクトリを作成し、ここに次のファイルを格納します(注: SampleAznおよびSampleActionクラスはsampleパッケージ内にある)。
  3. 「sample」ディレクトリのサブディレクトリを作成し、「module」という名前を付けます。ここに次のものを格納します(注: SampleLoginModuleクラスはsample.moduleパッケージ内にある)。
  4. 「sample」ディレクトリのサブディレクトリをもう1つ作成し、「principal」という名前を付けます。ここに次のものを格納します(注: SamplePrincipalクラスはsample.principalパッケージ内にある)。
  5. 最上位のディレクトリですべてのソース・ファイルをコンパイルします。
    javac sample/SampleAction.java sample/SampleAzn.java 
    sample/module/SampleLoginModule.java sample/principal/SamplePrincipal.java
    
    コマンド全体を1行に入力してください。
  6. SampleAzn.classおよびMyCallbackHandler.classを含むJARファイルSampleAzn.jarを作成します(注: これらのクラスのソース・ファイルはSampleAzn.java内にある)。
    jar -cvf SampleAzn.jar sample/SampleAzn.class 
    sample/MyCallbackHandler.class
    

    コマンド全体を1行に入力してください。

  7. SampleAction.classを含むSampleAction.jarという名前のJARファイルを作成します。
    jar -cvf SampleAction.jar sample/SampleAction.class
    
  8. SampleLoginModule.classSamplePrincipal.classを含むJARファイルを作成します。
    jar -cvf SampleLM.jar sample/module/SampleLoginModule.class 
    sample/principal/SamplePrincipal.class
    
  9. 次を指定して、SampleAznアプリケーションを実行します
    1. 適切な-classpath節(SampleAzn.jarSampleAction.jar、およびSampleLM.jar JARファイル内のクラスを検索するため)。
    2. -Djava.security.manager。セキュリティ・マネージャのインストールを指定します。
    3. -Djava.security.policy==sampleazn.policy。使用するポリシー・ファイルとしてsampleazn.policyを指定します。
    4. -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という名前のファイルが現在のディレクトリに存在するかどうかに関する文が表示されます。


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.