Java 認証・承認サービス (JAAS) 1.0

Java™認証・承認サービス (JAAS) は、Java 2 Software Development Kit、標準拡張機能です。 現在、Java 2 は、コード・ソースに基づくアクセス制御 (コードの発信元 およびコードの署名者 に基づいたアクセス制御) を提供しています。 ただし、コードの実行者 に基づく追加のアクセス制御を実施する機能に欠けています。 JAAS が提供するフレームワークでは、このサポートとともに Java 2 セキュリティー・モデルを拡大しています。

開発者用ガイド

リファレンス

概説

Java認証・承認サービス (JAAS) は、Java 2 Software Development Kit、バージョン 1.3 の標準拡張機能です。 現在、Java 2 は、コード・ソースに基づくアクセス制御 (コードの発信元 およびコードの署名者 に基づいたアクセス制御) を提供しています。 ただし、コードの実行者 に基づく追加のアクセス制御を実施する機能に欠けています。 JAAS が提供するフレームワークでは、このサポートとともに Java 2 セキュリティー・モデルを拡大しています。

この資料は、2000 年 3 月 17 日に最終更新されました。

この資料の対象読者

この資料は、コード・ソース・ベースのセキュリティー・モデルと Subject ベースのセキュリティー・モデルによって制限されたアプリケーションを作成しようとしている、経験を積んだプログラマーを対象としています。

関連資料

この資料は、読者が以下の資料をすでに読み終えていることを前提としています。

このガイドの補足は、Sun Microsystems, Inc. が提供する LoginModule Developer's Guide です。

紹介

JAAS インフラストラクチャーは、2 つのメイン・コンポーネント、すなわち認証コンポーネントと権限 (承認) コンポーネントに分割できます。 JAAS 認証コンポーネントは、Java がアプリケーション、アプレット、Bean、またはサーブレットとして稼働しているかどうかにかかわりなく、現在だれがそのコードを処理しているかについて確実かつ安全に判別する機能を提供します。 JAAS 権限 (承認) コンポーネントは、そのコード・ソース (Java 2 で実行される) に応じて、また認証された人物に応じて、処理中の Java コードが機密タスクを実行するのを制約することにより、既存の Java 2 セキュリティー・フレームワークを補足します。

JAAS 認証は、プラグ可能 形式で実行されます。 これにより、Java アプリケーションは、基礎となる認証テクノロジーからの独立を保つことが可能になります。 したがって、アプリケーションそのものに変更を加えなくても、新規または更新された認証テクノロジーをアプリケーションの下で接続することができます。 アプリケーションは、

LoginContext
オブジェクトをインスタンス化することによって、認証プロセスを使用可能にし、次に認証テクノロジーを決定する
Configuration
を参照するか、認証の実行時に使用される
LoginModule
を参照します。 標準的な LoginModules はユーザー名およびパスワードを入力するようにプロンプトを出して、それらを確認します。 あるいは、音声または指紋のサンプルを読み取って、それらを確認する場合もあります。

コードを処理するユーザーが認証されると、JAAS 権限 (承認) コンポーネントが既存の Java 2 アクセス制御モデルとともに機能して、重要なリソースへのアクセスを保護します。

アクセス制御決定がコードの場所およびコードの署名者にのみ基づく (
CodeSource
) Java 2 とは異なり、JAAS アクセス制御決定は処理コードの
CodeSource
と、コードを実行するユーザーの両方、または
Subject
に基づきます。 JAAS ポリシーは Java 2 ポリシーを、関係のある Subject ベースの情報で拡張したものに過ぎないことに注意してください。 そのため、Java 2 で認識され、理解される許可 (たとえば、
java.io.FilePermission
および
java.net.SocketPermission
) も JAAS によって理解され、認識されます。 さらに、JAAS セキュリティー・ポリシーは既存の Java 2 セキュリティー・ポリシーとは物理的に分離しているにもかかわらず、2 つのポリシーは一緒に 1 つの論理ポリシーを形成します。

コア・クラス

JAAS コア・クラスは、3 つのカテゴリーである共通、認証、および権限に分けることができます。

共通クラス

共通クラスは、JAAS 認証コンポーネントと権限 (承認) コンポーネントの両方に共有されます。

主要な JAAS クラスは
Subject
で、単一のエンティティー (個人など) に関連した情報のグループを表します。 これは、エンティティーのプリンシパル、公開信任状、および秘密信任状を包含します。

JAAS は、既存の Java 2
java.security.Principal
インターフェースを使用して、プリンシパルを表すことに注意してください。また、JAAS は別個の信任状インターフェースまたはクラスを導入しないことにも注意してください。 JAAS によって定義される信任状は任意のオブジェクトです。

Subject

リソースへのアクセスを許可するには、アプリケーションは最初に要求のソースを認証する必要があります。 JAAS フレームワークは、要求のソースを表すために、サブジェクトという用語を定義します。 サブジェクトは任意のエンティティー (個人またはサービスなど) です。 サブジェクトが認証されると、そこに関連した ID、つまりプリンシパルが取り込まれます。 サブジェクトは多数のプリンシパルを持つことがあります。 たとえば、ある個人が名前プリンシパル ("John Doe") と、それを他のサブジェクトと区別する SSN プリンシパル ("123-45-6789") を持つことがあります。

また、

Subject
がセキュリティー関連の属性を持つこともあります。これを信任状と言います。 特殊な保護を必要とする重要な信任状 (秘密暗号鍵など) は、秘密信任状
Set
に保管されます。 共有されることが意図されている信任状 (公開鍵証明書または Kerberos チケットなど) は、公開信任状
Set
に保管されます。 アクセスして変更する信任状セットが異なれば、それに応じた異なる許可が必要です。

サブジェクトは次のコンストラクターを使用して作成されます。

    public Subject();

    public Subject(boolean readOnly, Set principals,
                   Set pubCredentials, Set privCredentials);
最初のコンストラクターは、プリンシパルおよび信任状の空 (非ヌル) のセットを持つサブジェクトを作成します。 2 番目のコンストラクターは、プリンシパルおよび信任状の指定されたセットを持つサブジェクトを作成します。 また、読み取り専用サブジェクト (不変のプリンシパルおよび信任状セット) を作成できるブール引数を持っています。

これらのコンストラクターを使用しないで、認証済みサブジェクトへの参照を取得する代わりの方法が、LoginContext セクションに示されています。

サブジェクトが読み取り専用状態になるようにインスタンス化されなかった場合、次のメソッドを呼び出すことによって、読み取り専用状態に設定することができます。

    public void setReadOnly();
このメソッドを呼び出すには、
AuthPermission("setReadOnly")
が必要です。読み取り専用状態になったら、プリンシパルまたは信任状を追加または削除しようとすると、
IllegalStateException
が出されます。

サブジェクトの読み取り専用状態をテストするには、次のメソッドを呼び出すことができます。

    public boolean isReadOnly();
サブジェクトに関連したプリンシパルを検索するには、次の 2 つのメソッドが使用可能です。
    public Set getPrincipals();
    public Set getPrincipals(Class c);
最初のメソッドは、サブジェクトに含まれるすべてのプリンシパルを戻し、2 番目のメソッドは、指定されたクラス c のインスタンスまたはクラス c のサブクラスのインスタンスであるプリンシパルだけを戻します。サブジェクトに関連したプリンシパルがない場合には、空のセットが戻されます。

サブジェクトに関連した公開信任状を検索するには、次のメソッドが使用可能です。

    public Set getPublicCredentials();
    public Set getPublicCredentials(Class c);
これらのメソッドで観察される動作は、
getPrincipals
メソッドの動作と同一です。

サブジェクトに関連した秘密信任状を検索するには、次のメソッドが使用可能です。

    public Set getPrivateCredentials();
    public Set getPrivateCredentials(Class c);
これらのメソッドで観察される動作は、
getPrincipals
および
getPublicCredentials
メソッドの動作と同一です。

サブジェクトのプリンシパル・セット、公開信任状セット、または秘密信任状セットを変更するか、またはそれに対する操作を行うには、呼び出し元が
java.util.Set
クラスで定義されたメソッドを使用します。 次の例は、このことを示しています。
    Subject subject;
    Principal principal;
    Object credential;

    // add a Principal and credential to the Subject
    subject.getPrincipals().add(principal);
    subject.getPublicCredentials().add(credential);
それぞれのセットを変更するには、
AuthPermission("modifyPrincipals")
AuthPermission("modifyPublicCredentials")
、または
AuthPermission("modifyPrivateCredentials")
が必要です。 また、
getPrincipals
getPublicCredentials
、および
getPrivateCredentials
メソッドから戻されるセットだけが、サブジェクトのそれぞれの内部セットによって戻されることに注意してください。 そのため、戻されたセットに対する変更は、内部セットにも影響を与えます。
getPrincipals(Class c)
getPublicCredentials(Class c)
、および
getPrivateCredentials(Class c)
メソッドから戻されるセットは、サブジェクトのそれぞれの内部セットによって戻されません。 メソッドの呼び出しのたびに、新規セットが作成されて戻されます。 これらのセットに対する変更は、サブジェクトの内部セットに影響を与えません。 次のメソッドは、指定された
AccessControlContext
に関連したサブジェクトを戻すか、または指定した
AccessControlContext
に関連したサブジェクトがない場合には、ヌルを戻します。
    public static Subject getSubject(final AccessControlContext acc);
Subject.getSubject
を呼び出すには、
AuthPermission("getSubject")
が必要です。
また、Subject クラスには、
java.lang.Object
から継承された次のメソッドが含まれます。
    public boolean equals(Object o);
    public String toString();
    public int hashCode();

特定のサブジェクトとして処理を実行するために、次の静的メソッドを呼び出すことができます。

    public static Object doAs(final Subject subject,
                         final java.security.PrivilegedAction action);

    public static Object doAs(final Subject subject,
                         final java.security.PrivilegedExceptionAction action)
                         throws java.security.PrivilegedActionException;
どちらのメソッドも最初に、指定された subject を現行のスレッドの
AccessControlContext
に関連付け、次に action を処理します。これにより、actionsubject として実行されます。 最初のメソッドは実行時例外をスローすることがありますが、通常処理では、このメソッドはその action引数の run() メソッドから Object を戻します。 2 番目のメソッドは同様に動作しますが、その
PrivilegedExceptionAction 
run() メソッドからチェック済み例外をスローできる点が異なります。
 AuthPermission("doAs")
は、
doAs
メソッドを呼び出すために必要です。

最初の
doAs
メソッドを使用する 2 つの例を示します。 クラスが
com.ibm.security.Principal
で、"BOB" という名前のプリンシパルを持つ
Subject
LoginContext
"lc" によって認証されていることを想定します。 また、SecurityManager がインストールされており、JAAS アクセス制御ポリシーに以下が存在していることも想定しています (JAAS ポリシー・ファイルの詳細は、Policy セクションを参照してください)。
   // Grant "BOB" permission to read the file "foo.txt"
   grant Principal com.ibm.security.Principal "BOB" {
      permission java.io.FilePermission "foo.txt", "read";
};

Subject.doAs の例 1

    class ExampleAction implements java.security.PrivilegedAction {
        public Object run() {
            java.io.File f = new java.io.File("foo.txt");

            // exists() invokes a security check
            if (f.exists()) {
                System.out.println("File foo.txt exists.");
            }
            return null;
        }
    }

    public class Example1 {
        public static void main(String[] args) {

            // Authenticate the subject, "BOB".
            // This process is described in the
            // LoginContext section.

            Subject bob;
            ...

            // perform "ExampleAction" as "BOB":
            Subject.doAs(bob, new ExampleAction());
        }
    }
処理中に、
ExampleAction
では、
f.exists()
を呼び出す際にセキュリティー検査が行われます。 ただし、
ExampleAction
は "BOB" として実行しており、JAAS ポリシー (上述) は、必要な
FilePermission
を "BOB" に付与するため、
ExampleAction
はセキュリティー検査に合格します。

例 2 は、例 1 と同じシナリオを使用します。

Subject.doAs の例 2

    public class Example2 {
        // Example of using an anonymous action class.
        public static void main(String[] args) {
            // Authenticate the subject, "BOB".
            // This process is described in the
            // LoginContext section.

            Subject bob;
            ...

            // perform "ExampleAction" as "BOB":
            Subject.doAs(bob, new ExampleAction() {
                public Object run() {
                    java.io.File f = new java.io.File("foo.txt");
                    if (f.exists()) {
                        System.out.println("File foo.txt exists.");
                    }
                    return null;
                }
            });
        }
    }
例の permission grant ステートメントが間違って変更された場合 (正しくない CodeBase を追加したり、 Principal を "MOE" に変更するなど)、どちらの例も
SecurityException
をスローします。 grant ブロックから Principal フィールドを除去してから、それを Java 2 ポリシー・ファイルに移動させると、
SecurityException
はスローされません。なぜなら、ここでは許可がより一般的になっているからです (すべての プリンシパルに使用可能)。
どちらの例も同じ関数を実行するため、一方のコードを他方より優先するには理由が必要です。 例 1 は、無名クラスに精通していないプログラマーにとって、読み取りやすいでしょう。 また、action クラスは、固有の CodeBase を持つ個別のファイルに置くことができます。そうすると、permission grant はこの情報を使用できます。 例 2 はよりコンパクトで、実行される action は見つけるのが簡単です。なぜなら、
doAs
の呼び出しで実行されるからです。

さらに、次のメソッドも特定のサブジェクトとして処理を実行します。

ただし、
doAsPrivileged
メソッドには、提供された action および subject に基づいてセキュリティー検査があります。 提供されたコンテキストは、指定された subject および action に結びつけられます。 ヌル・コンテキスト・オブジェクトは、現行の
AccessControlContext
を完全に無視します。
    public static Object doAsPrivileged(final Subject subject,
                         final java.security.PrivilegedAction action,
                         final java.security.AccessControlContext acc);

    public static Object doAsPrivileged(final Subject subject,
                         final java.security.PrivilegedExceptionAction action,
                         final java.security.AccessControlContext acc)
                         throws java.security.PrivilegedActionException;
doAsPrivileged
メソッドは、次の点で
doAs
メソッドと同様に動作します。すなわち、subject はコンテキスト acc に関連付けられること、action が実行されること、および実行時例外またはチェック例外がスローされることです。 ただし、
doAsPrivileged
メソッドは、最初に既存のスレッドの
AccessControlContext
を空にしてから、subject を提供されたコンテキストに関連付けて、action を呼び出します。 ヌルの acc 引数を指定すると、アクセス制御決定 (action の処理中に呼び出される) は subjectaction だけに基づくことになります。
AuthPermission("doAsPrivileged")
は、
doAsPrivileged
メソッドを呼び出すときに必要です。

Principals

すでに説明したとおり、プリンシパルはサブジェクトに関連付けることができます。 プリンシパルは、サブジェクトの ID を表しており、
java.security.Principal
および
java.io.Serializable
インターフェースをインプリメントする必要があります。 Subject セクションでは、サブジェクトに関連したプリンシパルを更新する方法を説明しています。

Credentials

公開信任状クラスと秘密信任状クラスは、コア JAAS クラス・ライブラリーの一部ではありません。 そのため、どの java クラスでも信任状を表すことができます。 ただし、開発者はそれらの信任状クラスに、信任状に関連した 2 つのインターフェース、つまり Refreshable と Destroyable をインプリメントすることを選択できます。

Refreshable

このインターフェースは、信任状がそれ自身をリフレッシュする機能を提供します。 たとえば、特定の時間制限付きの有効期間を指定した信任状は、その信任状が有効である期間を呼び出し元がリフレッシュできるようにするためにこのインターフェースをインプリメントします。 インターフェースには次の 2 つの抽象メソッドがあります。
    boolean isCurrent();
信任状が現行、つまり有効かどうかを判別します。
    void refresh() throws RefreshFailedException;
信任状の妥当性を更新または拡張します。 このメソッドのインプリメンテーションでは、
AuthPermission("refreshCredential")
セキュリティー検査を実行して、呼び出し元が信任状をリフレッシュする許可を持つようにします。

Destroyable

このインターフェースは、信任状内の内容を破棄する機能を提供します。 インターフェースには次の 2 つの抽象メソッドがあります。
    boolean isDestroyed();
信任状が破棄されているかどうかを判別します。
    void destroy() throws DestroyFailedException;
この信任状に関連した情報を破棄して消去します。 これ以降に、この信任状に対して特定のメソッドを呼び出すと、
IllegalStateException
がスローされます。 このメソッドのインプリメンテーションでは、
AuthPermission("destroyCredential")
セキュリティー検査を実行して、呼び出し元が信任状を破棄する許可を持つようにします。

認証クラス

Subject
を認証するために、以下のステップが実行されます。
  1. アプリケーションは、
    LoginContext
    をインスタンス化します。
  2. LoginContext
    は構成を調べて、そのアプリケーション用に構成されたすべての LoginModules をロードします。
  3. アプリケーションは LoginContext の login メソッドを呼び出します。
  4. login メソッドは、ロードされたすべての LoginModules を呼び出します。 それぞれの
    LoginModule
    は、
    Subject
    の認証を試みます。 成功すると、LoginModules は関係のあるプリンシパルおよび信任状を
    Subject
    に関連付けます。
  5. LoginContext
    は認証状況をアプリケーションに戻します。
  6. 認証が成功すると、アプリケーションは認証済みの
    Subject
    LoginContext
    から取得します。

LoginContext

LoginContext
クラスは、サブジェクトを認証するために使用される基本メソッドを提供し、さらに基礎となる認証テクノロジーから独立してアプリケーションを開発する方法を提供します。
LoginContext
は構成
Configuration
を調べて、特定のアプリケーション用に構成された認証サービス、すなわち LoginModules を判別します。 したがって、アプリケーションそのものに変更を加えなくても、そのアプリケーションの下で様々な LoginModules を接続することができます。
LoginContext
は、選択できる以下の 4 つのコンストラクターを提供します。
    public LoginContext(String name) throws LoginException;

    public LoginContext(String name, Subject subject) throws LoginException;

    public LoginContext(String name, CallbackHandler callbackHandler)
           throws LoginException

    public LoginContext(String name, Subject subject,
           CallbackHandler callbackHandler) throws LoginException
すべてのコンストラクターは共通のパラメーター、name を共有します。 この引数は、ログイン構成に索引を付けるために、
LoginContext
によって使用されます。 入力パラメーターとして
Subject
を取らないコンストラクターは、新規の
Subject
をインスタンス化します。 すべてのコンストラクターで、ヌル入力は許可されません。 呼び出し元は、
AuthPermission("createLoginContext")
LoginContext
をインスタンス化することを求めます。

実際の認証は、次のメソッドの呼び出しとともに行われます。

    public void login() throws LoginException;
login が呼び出されると、構成された LoginModules のそれぞれの login メソッドがすべて、認証を実行するために呼び出されます。 認証が成功すると、認証済みの
Subject
(この時点で、プリンシパル、公開信任状、および秘密信任状を保有可能です) を、次のメソッドを使用して取得することができます。
    public Subject getSubject();
Subject
をログアウトし、その認証済みのプリンシパルおよび信任状を除去するために、次のメソッドが提供されています。
    public void logout() throws LoginException;

アプリケーション内の次のコードの断片は、"moduleFoo" という名前の構成項目を持つ構成ファイルにアクセスした後で、"bob" と呼ばれるサブジェクトを認証します。

    Subject bob = new Subject();
    LoginContext lc = new LoginContext("moduleFoo", bob);
    try {
        lc.login();
        System.out.println("authentication successful");
    } catch (LoginException le) {
        System.out.println("authentication unsuccessful"+le.printStackTrace());
    }
アプリケーション内の次のコードの断片は、「名前のない」サブジェクトを認証してから、getSubject メソッドを使用してそれを取得します。
    LoginContext lc = new LoginContext("moduleFoo");
    try {
        lc.login();
        System.out.println("authentication successful");
    } catch (LoginException le) {
        System.out.println("authentication unsuccessful"+le.printStackTrace());
    }
    Subject subject = lc.getSubject();
認証が失敗すると、getSubject はヌルを戻します。 また、
Subject.getSubject
の場合に存在した、これを行うために必要な
AuthPermission("getSubject")
はありません。

LoginModule

LoginModule インターフェースは、アプリケーションの下で接続できる様々な種類の認証テクノロジーをインプリメントする機能を開発者に提供します。 たとえば、
LoginModule
の 1 つのタイプでは、ユーザー名/パスワード・ベースの形式の認証を実行できます。

LoginModule Developer's Guide は、LoginModules をインプリメントするための段階的な説明を開発者に与える詳しい資料です。

LoginModule
をインスタンス化するためには、
LoginContext
は各
LoginModule
が、引数を取らない public コンストラクターを提供することを期待します。 次に、
LoginModule
を関連情報とともに初期化するために、
LoginContext
は、LoginModule の
initialize
メソッドを呼び出します。 提供された subject は、ヌル以外であることが保証されます。
   void initialize(Subject subject, CallbackHandler callbackHandler,
        Map sharedState, Map options);
次のメソッドは、認証プロセスを開始します。
     boolean login() throws LoginException;
メソッド・インプリメンテーションの例では、ユーザーにユーザー名とパスワードを入力するように促し、その後 NIS または LDAP などの命名サービスに保管されたデータと照らして情報を検査することができます。 代わりのインプリメンテーションでは、スマート・カードおよびバイオメトリック認証デバイスとのインターフェースをとり、単にユーザー情報を基礎となるオペレーティング・システムから抽出します。 これは、JAAS 認証プロセスのフェーズ 1 と見なされます。

次のメソッドは、認証プロセスを完了し、終了させます。

     boolean commit() throws LoginException;
認証プロセスのフェーズ 1 が成功した場合、このメソッドはフェーズ 2 を継続します。それは、プリンシパル、公開信任状、および秘密信任状をサブジェクトに関連付けることです。 フェーズ 1 が失敗した場合、commit メソッドは以前に保管された認証状態 (ユーザー名およびパスワードなど) を除去します。

次のメソッドは、フェーズ 1 が成功しなかった場合に認証プロセスを停止します。

    boolean abort() throws LoginException;
このメソッドの標準的インプリメンテーションでは、以前に保管された認証状態 (ユーザー名またはパスワードなど) をクリーンアップします。 次のメソッドは、サブジェクトをログアウトします。
    boolean logout() throws LoginException;
このメソッドは、元々
Subject
に関連付けられているプリンシパルおよび信任状を
commit
操作中に除去します。信任状は除去時に破棄されます。

CallbackHandler

場合によっては、LoginModule は、認証情報を取得するためにユーザーと通信しなければなりません。 LoginModules はこのために CallbackHandler を使用します。 アプリケーションは CallbackHandler インターフェースをインプリメントし、それを LoginContext に渡します。そして、基礎となる LoginModules に直接転送します。 LoginModules は、ユーザーからの入力 (パスワードまたはスマート・カード・ピン番号など) を収集することと、ユーザーに情報 (状況情報など) を提供することの両方のために、CallbackHandler を使用します。 アプリケーションが CallbackHandler を指定できるようにすることにより、基礎となる LoginModules は、アプリケーションがユーザーと対話する様々な方法からは独立したままでいられます。 たとえば、GUI アプリケーション用の CallbackHandler をインプリメントすると、ユーザーからの入力を送信請求するためにウィンドウが表示されます。 非 GUI ツール用の CallbackHandler をインプリメントすると、ユーザーはコマンド行から直接入力するように促されます。

CallbackHandler
は、以下をインプリメントするための 1 つのメソッドとのインターフェースです。
     void handle(Callback[] callbacks)
     throws java.io.IOException, UnsupportedCallbackException;

Callback

javax.security.auth.callback パッケージには、Callback インターフェースといくつかのインプリメンテーションが含まれています。 LoginModules は、Callback の配列を CallbackHandler の handle メソッドに直接渡します。

使用法の詳細については、各種の Callback API を調べてください。

権限クラス

Subject
の認証が成功すると、Subject.doAs または Subject.doAsPrivileged メソッドを呼び出すことにより、きめ細かいアクセス制御をその
Subject
に対して設定することができます。 その
Subject
に付与された許可は、JAAS
Policy
に構成されます。

Policy

これは、システム規模の JAAS アクセス制御を表すための抽象クラスです。 デフォルトとして、JAAS はファイル・ベースのサブクラス・インプリメンテーション、PolicyFile を提供します。 それぞれの
Policy
サブクラスは、以下のメソッドをインプリメントする必要があります。
    public abstract java.security.PermissionCollection getPermissions
                    (Subject subject,
                    java.security.CodeSource cs);
    public abstract void refresh();
getPermissions
メソッドは、指定された
Subject
および
CodeSource
に付与された許可を戻します。
refresh
メソッドは、ランタイム
Policy
を、それが永続ストア (例えば、ファイルまたはデータベース) から最後にロードされて以降に加えられた変更で更新します。
refresh
メソッドは、
AuthPermission("refreshPolicy")
を必要とします。
次のメソッドは、現行のランタイム
Policy
オブジェクトを取得し、呼び出し元に
AuthPermission("getPolicy")
を持つことを求めるセキュリティー検査で保護されています。
    public static Policy getPolicy();
次のコードの例は、
Policy
オブジェクトを照会して、指定された
Subject
および
CodeSource
に付与された許可のセットを調べる方法を示しています。
    policy = Policy.getPolicy();
    PermissionCollection perms = policy.getPermissions(subject, codeSource);
Java ランタイムに新規の
Policy
を設定するには、
Policy.setPolicy
メソッドを使用します。 このメソッドは、呼び出し元が
AuthPermission("setPolicy")
を持っていることを必要とします。
    public static void setPolicy(Policy policy);

ポリシー・ファイルのサンプル項目:

これらの例は、デフォルトの PolicyFile インプリメンテーションにのみ関係があります。

Policy
内の各項目は、grant 項目として表されます。 各 grant 項目は、codebase/code-signers/Principals トリプレットを指定すると同時に、そのトリプレットに付与される許可を指定します。 特に、指定された codebase からダウンロードされ、指定された code signers によって署名されたコードに、許可が付与されます。このことは、そのコードを実行する
Subject
が、指定されたすべての Principals をその
Principal
セットに持っている限り行われます。
Subject
が実行中のコードに関連付けられる様子については、Subject.doAs の例 を参照してください。
    grant CodeBase ["URL"],
          Signedby ["signers"],
          Principal [Principal_Class] "Principal_Name",
          Principal ... {
        permission Permission_Class ["Target_Name"]
                                    [, "Permission_Actions"]
                                    [, signedBy "SignerName"];
    };

    // example grant entry
    grant CodeBase "http://griffin.ibm.com", Signedby "davis",
          Principal com.ibm.security.auth.NTUserPrincipal "kent" {
        permission java.io.FilePermission "c:/kent/files/*", "read, write";
    };
Principal 情報が JAAS
Policy
grant 項目で指定されていない場合、構文解析例外がスローされます。ただし、通常の Java 2 コード・ソース・ベースのポリシー・ファイルにすでに存在している (したがって、Principal 情報を持たない) grant 項目は、依然として有効です。 そのような場合、Principal 情報は '*' (grant 項目はすべてのプリンシパルに適用される) であることが暗示されます。

grant 項目の CodeBase および Signedby コンポーネントは、JAAS
Policy
ではオプションです。 それらが存在しない場合、どんなコードベースでもマッチングし、さらにどんな署名者 (符号なしコードを含む) でもマッチングします。

上記の例では、grant 項目は、"http://griffin.ibm.com" からダウンロードされ、"davis" によって署名されて、NT ユーザー "kent" として実行しているコードが、1 つの
Permission
を持つことを指定します。 この
Permission
は、処理コードがディレクトリー "c:¥kent¥files" にあるファイルの読み取り/書き込みを行うことを許可します。
複数のプリンシパルが 1 つの grant 項目内にリストされることがあります。 コードを実行している現行の
Subject
は、その
Principal
セット内の指定されたすべてのプリンシパルが項目の許可を付与されるようにする必要があります。
    grant Principal com.ibm.security.auth.NTUserPrincipal "kent",
          Principal com.ibm.security.auth.NTSidGroupPrincipal "S-1-1-0" {
        permission java.io.FilePermission "c:/user/kent/", "read, write";
        permission java.net.SocketPermission "griffin.ibm.com", "connect";
    };
この項目は、NT グループ識別番号が "S-1-1-0" の NT ユーザー "kent" として実行する任意のコードに、 "c:¥user¥kent" にあるファイルの読み取りおよび書き込みを行う許可と、"griffin.ibm.com" に対するソケット接続を行う許可の両方を付与します。

AuthPermission

このクラスは、JAAS に必要な基本的な許可をカプセル化します。 AuthPermission には、名前 (「ターゲット名」とも言われる) が含まれますが、アクション・リストは含まれません。名前付きの許可はあってもなくてもかまいません。 (
Permission
クラスから) 継承されたメソッドに加えて、
AuthPermission
には、次の 2 つの public コンストラクターがあります。
    public AuthPermission(String name);
    public AuthPermission(String name, String actions);
最初のコンストラクターは、指定された名前を持つ新規の AuthPermission を作成します。 2 番目のコンストラクターも、指定された名前を持つ新規の AuthPermission オブジェクトを作成しますが、追加の actions 引数 (現在は未使用で、ヌルになっている) を持っています。 このコンストラクターは、新規の Permission オブジェクトをインスタンス化するために、
Policy
オブジェクト用にのみ存在します。たいていのコードの場合、最初のコンストラクターが適切です。

AuthPermission オブジェクトは、Policy、Subject、LoginContext、および Configuration オブジェクトへのアクセスを保護するために使用されます。 サポートされる有効な名前のリストについては、AuthPermission Javadoc を参照してください。

PrivateCredentialPermission

このクラスは、Subject の秘密信任状へのアクセスを保護し、1 つの public コンストラクターを提供します。
    public PrivateCredentialPermission(String name, String actions);
このクラスの詳細については、PrivateCredentialPermission Javadoc を参照してください。

インプリメンテーション

注: 付録 A には、ここで説明する静的プロパティーを含む、サンプルの java.security ファイルが記載されています。

JAAS プロバイダーおよびポリシー・ファイルにはデフォルト値が存在するため、ユーザーは JAAS をインプリメントするためにそれらのリストを静的に (java.security ファイル内で) リストすることも、動的に (コマンド行 -D オプション) リストすることも必要ありません。 また、デフォルト構成およびポリシー・ファイル・プロバイダーは、ユーザー開発のプロバイダーによって置き換えられることがあります。 そのため、このセクションでは、JAAS デフォルト・プロバイダーおよびポリシー・ファイルとともに、代わりのプロバイダーを使用可能にするプロパティーの説明を試みます。

ここで要約される事柄よりも詳しい情報については、Default Policy File API および Default Configuration File API をお読みください。

認証プロバイダー

認証プロバイダー、または構成クラスは、
login.configuration.provider=[class]
とともに java.security ファイルで静的に設定されます。 このプロバイダーは、
Configuration
オブジェクトを作成します。

以下に例を示します。

  login.configuration.provider=com.foo.Config
セキュリティー・プロパティー
login.configuration.provider
が java.security にない場合、JAAS はそれを次のデフォルト値に設定します。
com.ibm.security.auth.login.ConfigFile

Configuration
が作成される前にセキュリティー・マネージャーが設定される場合、
AuthPermission("getLoginConfiguration")
が付与される必要があります。

構成プロバイダーをコマンド行で動的に設定する方法はありません。

認証構成ファイル

認証構成ファイルは、java.security
login.config.url.n=[URL]
とともに静的に設定されます。ここで、n は 1 から始まる連続する整数です。 フォーマットは、Java セキュリティー・ポリシー・ファイル (policy.url.n=[URL]) のフォーマットと同一です。
セキュリティー・プロパティー
policy.allowSystemProperty
が java.security で "true" に設定される場合、ユーザーは次のプロパティーとともに -D オプションを使用して、コマンド行でポリシー・ファイルを動的に設定することができます。
java.security.auth.login.config
。値はパスまたは URL です。 例 (NT の場合):
  ... -Djava.security.auth.login.config=c:¥config_policy¥login.config ...
  または
  ... -Djava.security.auth.login.config=file:c:/config_policy/login.config ...
注: コマンド行で二重等号 (==) を使用すると、ユーザーは見つかったその他のすべてのポリシー・ファイルをオーバーライドすることができます。

構成ファイルが静的または動的に見つからない場合、JAAS は構成ファイルを次のデフォルト位置からロードしようとします。

${user.home}¥.java.login.config
ここで、${user.home} はシステムに依存する位置です。

権限プロバイダー

権限プロバイダー、または JAAS Policy クラスは、
auth.policy.provider=[class]
とともに java.security ファイルで静的に設定されます。 このプロバイダーは、JAAS サブジェクト・ベースの
Policy
オブジェクトを作成します。

以下に例を示します。

  auth.policy.provider=com.foo.Policy
セキュリティー・プロパティー
auth.policy.provider
が java.security にない場合、JAAS はそれを次のデフォルト値に設定します。
com.ibm.security.auth.PolicyFile
Configuration
が作成される前にセキュリティー・マネージャーが設定される場合、
AuthPermission("getPolicy")
が付与される必要があります。

権限プロバイダーをコマンド行で動的に設定する方法はありません。

権限ポリシー・ファイル

権限ポリシー・ファイルは、java.security
auth.policy.url.n=[URL]
とともに静的に設定されます。ここで、n は 1 から始まる連続する整数です。 フォーマットは、Java セキュリティー・ポリシー・ファイル (policy.url.n=[URL]) のフォーマットと同一です。
セキュリティー・プロパティー
policy.allowSystemProperty
が java.security で "true" に設定される場合、ユーザーは次のプロパティーとともに -D オプションを使用して、コマンド行でポリシー・ファイルを動的に設定することができます。
java.security.auth.policy
。値はパスまたは URL です。 例 (NT の場合):
  ... -Djava.security.auth.policy=c:¥auth_policy¥java.auth.policy ...
  または
  ... -Djava.security.auth.policy=file:c:/auth_policy/java.auth.policy ...
注: コマンド行で二重等号 (==) を使用すると、ユーザーは見つかったその他のすべてのポリシー・ファイルをオーバーライドすることができます。

権限ポリシーのロード元にするデフォルト位置はありません。

"Hello World"、JAAS スタイル!

黒っぽいサングラスをかけ、お気に入りのフェドーラ帽をかぶり、手にはアルト・サックスを取り ... JAAS-y を始めるときが来ました! これがもう一つの "Hello World!" プログラムです。 このセクションでは、JAAS インストールをテストするためのプログラムを使用可能にします。

インストール: JAAS がインストールされていることが想定されています。 たとえば、JAAS JAR ファイルがご使用の Development Kit の extensions ディレクトリーにコピーされています。

ファイルの取得: HelloWorld.tar をご使用のテスト・ディレクトリーにダウンロードします。 "jar xvf HelloWorld.tar" を使用して、それを解凍します。

テスト・ディレクトリーの内容を検査します。

ソース・ファイル: クラス・ファイル ポリシー・ファイル

ソース・ファイルのコンパイル: 3 つのソース・ファイル、HWLoginModule.javaHWPrincipal.java、および HelloWorld.java はすでにコンパイルされているため、コンパイルする必要はありません。

ソース・ファイルが変更される場合、それらが保管されているテスト・ディレクトリーに変更して、次のように入力します。

javac -d .¥classes *.java
クラスパスに classes ディレクトリー (.¥classes) を追加して、クラスをコンパイルできるようにする必要があります。

注:

HWLoginModule
および
HWPrincipal
は、
com.ibm.security
パッケージにあり、コンパイル時に適切なディレクトリー (>test_dir<¥classes¥com¥ibm¥security) に作成されます。

ポリシー・ファイルの調査: 構成ファイル jaas.config には次の 1 つの項目が含まれています。

helloWorld {
   com.ibm.security.HWLoginModule required debug=true;
};
1 つの
LoginModule
だけがテスト・ケースに提供されます。HelloWorld アプリケーションを処理するときには、
LoginModuleControlFlag
(required、requisite、sufficient、optional) を変えたり、デバッグ・フラグを削除したりして、試してみてください。 テストで利用できる LoginModule が他にもある場合、この構成を自由に変えて複数の LoginModule で試してみることもできます。
HWLoginModule
について、簡単に説明します。

Java 2 ポリシー・ファイル、java2.policy には、1 つの許可ブロックが含まれています。

grant {
   permission javax.security.auth.AuthPermission "createLoginContext";
   permission javax.security.auth.AuthPermission "modifyPrincipals";
   permission javax.security.auth.AuthPermission "doAsPrivileged";
};
HelloWorld アプリケーションは、(1) LoginContext オブジェクトを作成し、(2) 認証された
Subject
のプリンシパルを変更し、(3)
Subject
クラスの doAsPrivileged メソッドを呼び出すため、3 つの許可が必要です。

JAAS ポリシー・ファイル jaas.policy にも、1 つの許可ブロックが含まれています。

grant Principal com.ibm.security.HWPrincipal "bob" {
   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "foo.txt", "read";
};
3 つの許可は、最初に bob という名前の
HWPrincipal
に認可されます。 認証された
Subject
に追加される実際のプリンシパルは、ログイン・プロセス (さらに後) で使用されるユーザー名です。

以下に HelloWorld のアクション・コードを示します。 3 つのシステム呼び出し (許可が必要である理由) がボールド体で示されています。
Subject.doAsPrivileged(lc.getSubject(), new PrivilegedAction() {
    public Object run() {
        System.out.println("¥nYour java.home property: "
                           +System.getProperty("java.home"));

        System.out.println("¥nYour user.home property: "
                           +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 your current directory");

        System.out.println("¥nOh, by the way ...");

                try {
            Thread.currentThread().sleep(2000);
        } catch (Exception e) {
            // ignore
        }
        System.out.println("¥n¥nHello World!¥n");
        return null;
    }
}, null);
HelloWorld プログラムを実行するときは、さまざまなユーザー名を使用し、それに応じて jaas.policy を変更できます。 java2.policy を変更する必要はありません。 また、テスト・ディレクトリー内に foo.txt というファイルを作成して、最後のシステム呼び出しをテストします。

ソース・ファイルの調査:

LoginModule、
HWLoginModule
は、正しいパスワード (大文字小文字の区別がある) を入力したユーザーを認証します: Go JAAS

HelloWorld アプリケーションでは、ユーザーは 3 回までパスワードの入力を試みることができます。 Go JAAS が正しく入力されると、ユーザー名と同じ名前を持つ

HWPrincipal
が、認証された
Subject
に追加されます。

Principal クラスの
HWPrincipal
は、入力されたユーザー名に基づくプリンシパルを表します。 この名前は、認証されたサブジェクトに許可を与える際に重要になります。

メイン・アプリケーションの
HelloWorld
は、helloWorld という名前の構成項目に基づいて、
LoginContext
をまず作成します。 構成ファイルについてはすでに説明されています。 ユーザー入力を検索するためにコールバックが使用されます。 このプロセスを調べるには、HelloWorld.java ファイルにある
MyCallbackHandler
クラスを参照してください。
    LoginContext lc = null;
    try {
        lc = new LoginContext("helloWorld", new MyCallbackHandler());
    } catch (LoginException le) {
        le.printStackTrace();
        System.exit(-1);
    }
ユーザーがユーザー名とパスワードを (最大 3 回) 入力し、Go JAAS がパスワードとして入力されると、サブジェクトは認証されます (
HWLoginModule
によってサブジェクトに
HWPrincipal
が追加されます)。

すでに説明したとおり、以後の作業は、認証されたサブジェクトとして実行されます。

HelloWorld テストの実行

HelloWorld プログラムを実行するには、最初にテスト・ディレクトリーに変更します。 構成およびポリシー・ファイルをロードする必要があります。 正しいプロパティーについてインプリメンテーションを参照して、 java.security かコマンド行のいずれかに設定します。 後者のメソッドについて、これから説明します。

以下のコマンドは、明確にするために複数の行に分割されています。 1 つの連続するコマンドとして入力してください。

java -Djava.security.manager=
     -Djava.security.auth.login.config=.¥jaas.config
     -Djava.security.policy=.¥java2.policy
     -Djava.security.auth.policy=.¥jaas.policy
     HelloWorld
注: 各ユーザーのテスト・ディレクトリー標準パスは異なるため、ポリシー・ファイルに ".¥filename" を使用することが必要です。 希望する場合は、 "." をテスト・ディレクトリーへのパスの代わりにしてください。 たとえば、テスト・ディレクトリーが "c:¥test¥hello" の場合、最初のファイルは次のように変更されます。
     -Djava.security.auth.login.config=c:¥test¥hello¥jaas.config
ポリシー・ファイルが見つからない場合は、
SecurityException
がスローされます。 見つかった場合は、 java.home および user.home プロパティーに関する情報が表示されます。 また、テスト・ディレクトリーに foo.txt というファイルがあるかどうかが検査されます。 最後に、いたるところに "Hello World" というメッセージが表示されます。

HelloWorld を楽しむ

好きなだけ HelloWorld を再実行してください。 入力したユーザー名/パスワードを変え、構成ファイル項目を変更し、ポリシー・ファイル許可を変更し、さらに追加の LoginModules を helloWorld 構成項目に追加する (積み重ねる) ことまで、すでに提案されました。 さらに、codebase フィールドをポリシー・ファイルに追加することができます。

最後に、セキュリティー・マネージャーなしでプログラムを実行して、問題発生時における動作を調べてみてください。

付録 A: java.security セキュリティー・プロパティー・ファイル・ファイルでの JAAS 設定

以下に示すのは、すべての Java 2 インストールに現れる
java.security
ファイルです。 このファイルは、Java 2 ランタイムの
lib/security
(Windows® では
lib¥security
) ディレクトリーに現れます。 したがって、Java 2 ランタイムが
jdk1.3
というディレクトリーにインストールされている場合、ファイルは以下のようになります。 JAAS は 4 つの新規のプロパティーを
java.security
に追加します。

新規の JAAS プロパティーは、このファイルの末尾に置かれます。

#
# This is the "master security properties file".
#
# In this file, various security properties are set for use by
# java.security classes. This is where users can statically register
# Cryptography Package Providers ("providers" for short). The term
# "provider" refers to a package or set of packages that supply a
# concrete implementation of a subset of the cryptography aspects of
# the Java Security API. A provider may, for example, implement one or
# more digital signature algorithms or message digest algorithms.
#
# Each provider must implement a subclass of the Provider class.
# To register a provider in this master security properties file,
# specify the Provider subclass name and priority in the format
#
#    security.provider.n=className
#
# This declares a provider, and specifies its preference
# order n. The preference order is the order in which providers are
# searched for requested algorithms (when no specific provider is
# requested). The order is 1-based; 1 is the most preferred, followed
# by 2, and so on.
#
# className must specify the subclass of the Provider class whose
# constructor sets the values of various properties that are required
# for the Java Security API to look up the algorithms or other
# facilities implemented by the provider.
#
# There must be at least one provider specification in java.security.
# There is a default provider that comes standard with the JDK. It
# is called the "SUN" provider, and its Provider subclass
# named Sun appears in the sun.security.provider package. Thus, the
# "SUN" provider is registered via the following:
#
#    security.provider.1=sun.security.provider.Sun
#
# (The number 1 is used for the default provider.)
#
# Note: Statically registered Provider subclasses are instantiated
# when the system is initialized. Providers can be dynamically
# registered instead by calls to either the addProvider or
# insertProviderAt method in the Security class.

#
# List of providers and their preference orders (see above):
#
security.provider.1=sun.security.provider.Sun

#
# Class to instantiate as the system Policy. This is the name of the class
# that will be used as the Policy object.
#
policy.provider=sun.security.provider.PolicyFile 
# The default is to have a single system-wide policy file,
# and a policy file in the user's home directory.
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy

# whether or not we expand properties in the policy file
# if this is set to false, properties (${...}) will not be expanded in policy
# files.
policy.expandProperties=true

# whether or not we allow an extra policy to be passed on the command line
# with -Djava.security.policy=somefile. Comment out this line to disable
# this feature.
policy.allowSystemProperty=true

# whether or not we look into the IdentityScope for trusted Identities
# when encountering a 1.1 signed JAR file. If the identity is found
# and is trusted, we grant it AllPermission.
policy.ignoreIdentityScope=false

#
# Default keystore type.
#
keystore.type=jks

#
# Class to instantiate as the system scope:
#
system.scope=sun.security.provider.IdentityDatabase

##############################################################################
#
# Java Authentication and Authorization Service (JAAS)
# properties and policy files:
#

# Class to instantiate as the system Configuration for authentication.
# This is the name of the class that will be used as the Authentication
# Configuration object.
#
login.configuration.provider=com.ibm.security.auth.login.ConfigFile 
# The default is to have a system-wide login configuration file found in
# the user's home directory.  For multiple files, the format is similar to
# that of CodeSource-base policy files above, that is policy.url.n
login.config.url.1=file:${user.home}/.java.login.config

# Class to instantiate as the system Principal-based Authorization Policy.
# This is the name of the class that will be used as the Authorization
# Policy object.
#
auth.policy.provider=com.ibm.security.auth.PolicyFile
# The default is to have a system-wide Principal-based policy file found in
# the user's home directory.  For multiple files, the format is similar to
# that of CodeSource-base policy files above, that is policy.url.n and
# auth.policy.url.n
auth.policy.url.1=file:${user.home}/.java.auth.policy

付録 B: ログイン構成ファイル

ログイン構成ファイルには、以下の形式の 1 つ以上の
LoginContext
アプリケーション名が含まれています。
Application {
    LoginModule Flag ModuleOptions;
    > more LoginModule entries <
    LoginModule Flag ModuleOptions;
};
ログイン構成ファイルは、
java.security
ファイルにある
login.config.url.n
セキュリティー・プロパティーを使用して配置されます。 このプロパティーおよび
java.security
ファイルの位置については、付録 A を参照してください。

Flag の値は、認証が回を重ねて進むときの全部的な動作を制御します。 以下は、Flag の有効な値と、それぞれの意味の説明を表しています。

  1. Required
    LoginModule
    は成功する必要があります。 成功しても失敗しても、認証は
    LoginModule
    リストの処理を引き続き先に進めます。
  2. Requisite
    LoginModule
    は成功する必要があります。成功すると、認証は
    LoginModule
    リストの処理を継続します。 失敗すると、制御はただちにアプリケーションに戻ります (認証は
    LoginModule
    リストの処理を先に進めません)。
  3. Sufficient
    LoginModule
    は成功しなくても構いません。成功すると、制御はただちにアプリケーションに戻ります (認証は
    LoginModule
    リストの処理を先に進めません)。 失敗すると、認証は
    LoginModule
    リストの処理を継続します。
  4. Optional
    LoginModule
    は成功しなくても構いません。成功しても失敗しても、認証は
    LoginModule
    リストの処理を引き続き先に進めます。

全体の認証は、すべての Required および Requisite の LoginModules が正常に実行される場合に限り成功します。

Sufficient
LoginModule
が構成されて成功する場合、全体の認証が成功するには、その Sufficient
LoginModule
の前に Required および Requisite の LoginModules だけが正常に実行される必要があります。 Required または Requisite の LoginModules がアプリケーション用に構成されていない場合、少なくとも 1 つの Sufficient または Optional
LoginModule
が成功する必要があります。

サンプル構成ファイル:

/*  Sample Configuration File  */

Login1 {
   com.ibm.security.auth.module.SampleLoginModule required debug=true;
};

Login2 {
   com.ibm.security.auth.module.SampleLoginModule required;
   com.ibm.security.auth.module.NTLoginModule sufficient;
   ibm.loginModules.SmartCard requisite debug=true;
   ibm.loginModules.Kerberos optional debug=true;
};
注: フラグには大文字小文字の区別がありません。 REQUISITE = requisite = Requisite です。

Login1 は、クラス
com.ibm.security.auth.module.SampleLoginModule
のインスタンスである 1 つの LoginModule のみ持っています。 したがって、Login1 に関連した
LoginContext
は、そのただ 1 つのモジュールが正常に認証を行う場合に限り、正常に認証されます。 Required フラグは、この例では意味がありません。複数のモジュールが存在するときに、フラグ値は認証に関係のある影響を与えます。

Login2 は、表を使って説明する方が簡単です。

Login2 認証状況
サンプル・ログイン・モジュール required pass pass pass pass fail fail fail fail
NT ログイン・モジュール sufficient pass fail fail fail pass fail fail fail
スマート・カード requisite * pass pass fail * pass pass fail
Kerberos optional * pass fail * * pass fail *
全体の認証 pass pass pass fail fail fail fail fail
* = 以前の REQUISITE モジュールが失敗したか、または以前の SUFFICIENT モジュールが成功したため、アプリケーションに制御が戻ったことによる、意味のない値。

付録 C: 権限ポリシー・ファイル

上記のプリンシパル・ベースの JAAS ポリシーの grant ブロックの例では十分でない場合、ここにさらに説明があります。

// SAMPLE JAAS POLICY FILE:  java.auth.policy

// The following permissions are granted to Principal 'Pooh' and all codesource:

grant Principal com.ibm.security.Principal "Pooh" {
   permission javax.security.auth.AuthPermission "setPolicy";
   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "c:/foo/jaas.txt", "read";
};

// The following permissions are granted to Principal 'Pooh' AND 'Eyeore'
// and CodeSource signedBy "DrSecure":

grant signedBy "DrSecure"
      Principal com.ibm.security.Principal "Pooh",
      Principal com.ibm.security.Principal "Eyeore" {
   permission javax.security.auth.AuthPermission "modifyPublicCredentials";
   permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
   permission java.net.SocketPermission "us.ibm.com", "connect,accept,resolve";
   permission java.net.SocketPermission "griffin.ibm.com", "accept";
};

// The following permissions are granted to Principal 'Pooh' AND 'Eyeore' AND
// 'Piglet' and CodeSource from the c:¥jaas directory signed by "kent" and "bruce":

grant codeBase "file:c:/jaas/*",
      signedBy "kent, bruce",
      Principal com.ibm.security.Principal "Pooh",
      Principal com.ibm.security.Principal "Eyeore",
      Principal com.ibm.security.Principal "Piglet"  {
   permission javax.security.auth.AuthPermission "getSubject";
   permission java.security.SecurityPermission "printIdentity";
   permission java.net.SocketPermission "guapo.ibm.com", "accept";
};