デフォルトの Policy の実装とポリシーファイルの構文

ドキュメント改訂 1.6

JavaTM プログラミング言語のアプリケーション環境のポリシーは、さまざまなソースを出所とするコードがどのようなアクセス権を使用できるかを指定し、さまざまなプリンシパルとして実行するもので、Policy オブジェクトによって表されます。具体的には、Policy クラス (java.security パッケージ内) で定義されている abstract メソッドを実装した Policy サブクラスによって表されます。

Policy オブジェクトが使用するポリシー情報がどこに置かれるかは、Policy の実装によります。Policy のリファレンス実装では、ポリシー情報を静的なポリシー構成ファイルから得ます。

このドキュメントでは、Policy のリファレンス実装と、それによって読み取られるポリシーファイルで使用する構文について説明します。 Policy Tool を使った (構文を知る必要のない) ポリシーファイルの作成方法の詳細については、Policy Tool のドキュメント (Solaris 用) (Win32 用) を参照してください。

このドキュメントでは、次の内容について説明します。

JavaTM 2 SDK, Standard Edition, v 1.4 での Policy の変更点
デフォルトの Policy の実装
ポリシーファイルのデフォルトの場所
ポリシーの実装の変更
ポリシーファイルの構文
ポリシーファイルの例
ポリシーファイルにおけるプロパティーの展開
ポリシーファイルにおける一般的な展開
関連ドキュメント

JavaTM 2 SDK, Standard Edition, v 1.4 での Policy の変更点

JavaTM 認証・承認サービス (JAAS) が、J2SDK, v 1.4 に統合されているので、java.security.Policy API は主体ベースのクエリーを扱い、デフォルト Policy の実装は主体ベースの grant エントリをサポートしています。このように、どのコードが実行されているかだけではなく、どの「ユーザー」が実行しているかに基づいて、アクセス制御を実行できるようになりました。プリンシパルベースの grant エントリの詳細については、このドキュメントのほかの節を参照してください。


注: このバージョン (v 1.4) 以降、デフォルトのポリシーの実装で使用されるポリシーファイルは、UTF-8 エンコーディング方式でエンコーディングする必要があります。この変換には、native2ascii ツールを使用できます。
この節で説明する内容は、Policy API を使用するプログラマだけに関係します。Policy API を使用しない場合は、次の「デフォルトの Policy の実装」「ポリシーファイルのデフォルトの場所」に進んでください。

J2SDK, v 1.4 でのポリシー関連 API の変更点には、以下の内容が含まれます。

デフォルトの Policy の実装

Policy のリファレンス実装では、1 つまたは複数のポリシー構成ファイルからポリシーを指定できます。ポリシー構成ファイルでは、指定されたコードソースからのコードに対してどのようなアクセス権を与え、指定されたプリンシパルとして実行するかを指定します。各設定ファイルは、UTF-8 方式でエンコードする必要があります。

ポリシーファイルは、単純なテキストエディタ、またはグラフィカルな Policy Tool ユーティリティーを使って作成できます。

デフォルトでは、システム全体のポリシーファイルが 1 つと、ユーザーポリシーファイル (オプション) が 1 つ存在します。

Policy のリファレンス実装は、その getPermissions メソッドがはじめて呼び出されたとき、あるいは、その refresh メソッドが呼び出されたときに初期化されます。初期化時には、ポリシー構成ファイル (「ポリシーファイルの構文」を参照) の解析が行われたあと、その情報が Policy オブジェクトに読み込まれます。

ポリシーファイルのデフォルトの場所

前述したように、デフォルトでは、システム全体のポリシーファイルが 1 つと、ユーザーポリシーファイルが 1 つ存在します。

システムポリシーファイルは、デフォルトでは次の場所にあります。

java.home/lib/security/java.policy  (Solaris)
java.home\lib\security\java.policy  (Win32)

注: java.home は、「java.home」という名前のシステムプロパティーの値で、実行環境の格納先ディレクトリ (Java 2 SDK の jre ディレクトリ、または Java 2 Runtime Environment の最上位ディレクトリ) を指します。

システムのポリシーファイルは、システム全体に渡ってコードにアクセス権を与えます。SDK に含まれている java.policy ファイルは、標準拡張機能にすべてのアクセス権を与え、ユーザーが特権のないポートで待機したり、「os.name」プロパティーや「file.separator」プロパティーなどの任意のコードがセキュリティーにかかわらない特定の「標準」プロパティーを読み込んだりすることを許可します。

ユーザーポリシーファイルは、デフォルトでは次の場所にあります。

user.home/.java.policy  (Solaris)
user.home\.java.policy  (Win32)

注: user.home は「user.home」という名前のシステムプロパティーの値で、ユーザーのホームディレクトリを指定します。Win32 のシステムでは、ユーザー名が uName の場合、user.home プロパティーの値はデフォルトでは次のように設定されます。

マルチユーザー Windows NT システムでは C:\Winnt\Profiles\uName
マルチユーザー Windows 95 システムでは C:\Windows\Profiles\uName
シングルユーザー Windows 95 システムでは C:\Windows

Policy が初期化されると、まずシステムポリシーがロードされ、次に、ロードされたシステムポリシーにユーザーポリシーが追加されます。どちらのポリシーも存在しない場合は、組み込みポリシーが使われます。組み込みポリシーは、JRE とともにインストールした java.policy ファイルと同じです。

ポリシーファイルの場所は、セキュリティープロパティーファイルの中で指定されています。セキュリティープロパティーファイルは、次の場所にあります。

java.home/lib/security/java.security  (Solaris)
java.home\lib\security\java.security  (Win32)
前述のように、java.home は実行環境の格納先ディレクトリ (Java 2 SDK の jre ディレクトリ、または Java 2 Runtime Environment の最上位ディレクトリ) を指します。 ポリシーファイルの場所は、次のような形式の名前を持つプロパティーの値として指定されています。
policy.url.n
n は数字です。次に示す形式の行で、それぞれのプロパティーの値を指定します。
policy.url.n=URL
ここで、URL は URL の指定を表します。

たとえば、デフォルトのシステムおよびユーザーポリシーファイルは、セキュリティープロパティーファイルに次のように指定されています。

policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy

${java.home} を使用して java.home プロパティーの値を指定するなど、特別な構文でプロパティーの値を指定する方法については、「ポリシーファイルにおけるプロパティーの展開」を参照してください。

URL をいくつも指定して (http:// 形式のものを含む)、該当するポリシーファイルをすべてロードすることもできます。また、上に示したポリシーファイルの指定のうち、2 番目のポリシーファイルの指定をコメントアウトするか、あるいは修正すれば、デフォルトユーザーポリシーファイルの読み込みを無効にすることができます。

アルゴリズムは、policy.url.1 から処理を開始して、番号を 1 つずつ増やしながら、URL が見つからなくなるまで処理を続けます。したがって、policy.url.1policy.url.3 がある場合、policy.url.3 は読み込まれません。

実行時に新しいポリシーファイルを指定する

アプリケーションを実行するときに、追加のポリシーファイルや別のポリシーファイルを指定することもできます。この場合は、-Djava.security.policy コマンド行引数を使って java.security.policy プロパティーの値を設定します。たとえば、次のように指定します。

    java -Djava.security.manager -Djava.security.policy=someURL SomeApp
someURL は、ポリシーファイルの場所を示す URL です。この例では、セキュリティープロパティーファイルで指定されたすべてのポリシーファイルに加えて、someURL で指定されたポリシーファイルがロードされます。

注 -

次のように指定することもできます。

    java -Djava.security.manager -Djava.security.policy==someURL SomeApp
等号が 2 つ使われていることに注意してください。この場合は、指定されたポリシーファイルだけが使われ、セキュリティープロパティーに示されたポリシーファイルはすべて無視されます。

ポリシーファイルを appletviewer (アプレットビューア) に渡す場合は、次のように -J-Djava.security.policy 引数を指定します。

    appletviewer -J-Djava.security.policy=someURL myApplet
-セキュリティープロパティーファイルで policy.allowSystemProperty プロパティーに false が設定されている場合は、-Djava.security.policy のポリシーファイルの値は (java コマンドと appletviewer コマンドのどちらの場合も) 無視されます。policy.allowSystemProperty プロパティーのデフォルト値は true です。

ポリシーの実装の変更

新しいポリシークラスを作成し、Policy のリファレンス実装クラスと置き換えることもできます。この場合は、Policy 抽象クラスのサブクラスを作成し、getPermissions メソッド (必要に応じてその他のメソッドも) を実装します。

セキュリティープロパティーファイル (SDK の lib/security ディレクトリの java.security ファイル) を編集すれば、Policy のリファレンス実装を変更できます。

java.security で設定できるプロパティーの例を次に示します。

    policy.provider=PolicyClassName

PolicyClassName には、目的の Policy 実装クラスを完全修飾名で指定します。デフォルトのセキュリティープロパティーファイルでは、このプロパティーは次のように指定されています。

    policy.provider=sun.security.provider.PolicyFile

カスタマイズするには、次のように、このプロパティーに別のクラスを指定します。

   policy.provider=com.mycom.MyPolicy

ポリシーファイルの構文

インストールした SDK のポリシー構成ファイルでは、指定されたコードソースからのコードに対し、どのようなアクセス権 (システムリソースへのアクセスの種類) を与え、指定したプリンシパルとして実行するかを指定します。

アプレット (またはセキュリティーマネージャーの下で動作しているアプリケーション) が、ファイルの読み書きなど、セキュリティー保護された操作を行うためには、その操作を行うためのアクセス権が与えられていなければなりません。Policy のリファレンス実装では、ポリシー構成ファイルの付与エントリによって、そのアクセス権を与えなければなりません。詳しくは、以降の説明と「Java セキュリティーアーキテクチャー」を参照してください。ただし、同じ (URL の) 場所にあるファイルと、その場所のサブディレクトリにあるファイルの読み取りアクセス権は、常に自動的に与えられます。したがって、そのようなアクセス権については、明示的に指定する必要はありません。

ポリシー構成ファイルは、エントリのリストで構成されます。1 つの keystore エントリと、0 以上の grant エントリを持たせることができます。

キーストアエントリ

「キーストア」は、非公開鍵と、対応する公開鍵を認証する X.509 証明書などのデジタル証明書が格納されたデータベースです。キーストアの作成と管理には、keytool ユーティリティー (Solaris 用)、(Win32 用) を使います。ポリシー設定ファイルで指定されているキーストアは、そのファイルの grant エントリで指定されている署名者の公開鍵を照合するために使用されます。署名者の別名を指定している grant エントリがある場合、またはプリンシパルの別名を指定している grant エントリがある場合は、ポリシー設定ファイルに必ず keystore エントリを置きます (次を参照)。

このとき、ポリシーファイル内で有効な keystore/keystorePasswordURL エントリは 1 つだけです。 最初のエントリ以外の後続エントリは無視されます。このエントリは、ファイルの grant エントリ外部の任意の場所に配置できます。keystore エントリの構文は次のとおりです。

keystore "some_keystore_url", "keystore_type", "keystore_provider";
keystorePasswordURL "some_password_url";
some_keystore_url にはキーストアの URL の場所を指定し、some_password_url にはキーストアパスワードの URL の場所を指定し、keystore_type にはキーストアの型を指定し、keystore_provider にはキーストアのプロバイダを指定します。some_keystore_url からの入力ストリームは KeyStore.load メソッドに渡されることに注意してください。URL として NONE が指定されている場合は、null のストリームが KeyStore.load メソッドに渡されます。NONE は、KeyStore がファイルベースではなく、たとえば、ハードウェアトークンデバイスに置かれている場合に指定します。

URL は、ポリシーファイルがある場所からの相対位置を表します。たとえば、セキュリティープロパティーファイルの中でポリシーファイルが次のように指定されているとします。

    policy.url.1=http://foo.bar.com/fum/some.policy
また、このポリシーファイルには、次のエントリがあるとします。
    keystore ".keystore";
この場合、キーストアは次の場所からロードされます。
    http://foo.bar.com/fum/.keystore
URL に絶対位置を指定することもできます。

キーストアのタイプは、キーストア情報の格納形式とデータ形式を定義するとともに、キーストア内の非公開鍵とキーストア自体の整合性を保護するために使われるアルゴリズムを定義します。Sun Microsystems がサポートするデフォルトのタイプは、Sun Microsystems に所有権があるキーストアタイプ名「JKS」です。したがって、キーストアのタイプが「JKS」であれば、キーストアエントリを指定する必要はありません。

付与エントリ

実行されるコードは、常に、特定の「コードソース」(CodeSource 型のオブジェクトによって表される) から来ると考えられます。コードソースは、コードの出所を表す場所 (URL) だけでなく、コードの署名に使われた非公開鍵に対応する公開鍵を含んだ証明書への参照も含みます。コードソース内の証明書は、ユーザーのキーストアからのシンボリックな別名によって参照されます。コードはさらに、特定のプリンシパル (Principal 型のオブジェクトによって表される) またはプリンシパルのグループとして実行されると考えられます。

付与エントリには、省略可能な codeBasesignedBy、およびプリンシパルの名前と値のペアのあとに、アクセス権を付与するコードを指定するいくつかの「アクセス権エントリ」が含まれます。付与エントリの基本形式は、次のとおりです。

  grant signedBy "signer_names", codeBase "URL",
        principal principal_class_name "principal_name",
        principal principal_class_name "principal_name",
        ... {

      permission permission_class_name "target_name", "action", 
          signedBy "signer_names";
      permission permission_class_name "target_name", "action", 
          signedBy "signer_names";
      ...
  };
 	
上の形式でイタリック体になっていない項目は、示されているとおりに指定します。ただし、大文字と小文字は区別されず、また、以降で説明するように、いくつかの項目は省略可能です。イタリックで示されている項目は、可変の項目です。

付与エントリは、grant で始まります。

SignedByPrincipal、および CodeBase フィールド

signedBycodeBase および principal の値は省略可能です。また、これらのフィールドの順序は問われません。

signedBy の値は、キーストアに格納された証明書の別名を示します。証明書内の公開鍵は、コードのデジタル署名の検証に使われます。別名によって指定されたキーストアエントリ内の公開鍵に対応する、非公開鍵で署名されたコードに、アクセス権を付与します。

signedBy の値には、複数の別名をコンマで区切って指定できます。たとえば、"Adam,Eve,Charles" のように指定できます。この場合は、各要素が OR ではなく AND で結ばれ、「Adam、Eve、および Charles によって署名された」という意味になります。より厳密には、「Adam によって署名されたコード」とは、「Adam という別名が付けられたエントリを持つキーストアにある公開鍵証明書に対応する、非公開鍵を使って署名された JAR ファイルに含まれている、クラスファイル内のコード」という意味です。

signedBy フィールドは省略可能です。省略した場合は、「任意の署名者」という意味になります。コードに署名が付いているかどうか、誰が署名しているかは問われなくなります。

プリンシパルの値は class_nameprincipal_name のペアを指定します。このペアは、実行中のスレッドのプリンシパルセット内にある必要があります。プリンシパルセットは、Subject によって実行するコードに関連付けられます。プリンシパルフィールドは省略可能です。省略した場合は、「任意のプリンシパル」という意味になります。

キーストアの別名の置き換え

principal class_name/principal_name のペアが単一引用符で囲まれた文字列として指定される場合は、キーストアの別名として扱われます。キーストアは別名を経由して X509 証明書を調査し、問い合わせます。キーストアがある場合は、principal class_name は自動的に javax.security.auth.x500.X500Principal として扱われ、principal_name は証明書で名前を識別されたサブジェクトとして自動的に扱われます。X509 証明書のマッピングが見つからない場合は、grant エントリはすべて無視されます。

codeBase の値は、コードが置かれる場所を示します。この場所からコードにアクセス権を付与します。codeBase エントリを省略した場合は、「任意のコード」という意味になり、コードの出所は問われません。

注: codeBase の値は URL であるため、コードソースが Win32 システム上にある場合であっても、ディレクトリの区切り文字は、バックスラッシュではなく、必ずスラッシュを使います。したがって、Win32 システム上でコードの場所が C:\somepath\app\ の場合、codeBase ポリシーエントリは次のように指定します。

    grant codeBase "file:/C:/somepath/api/" {
        ...
    }
codeBase の値の正確な意味は、末尾の文字によって変わります。末尾が「/」の codeBase は、指定されたディレクトリ内のすべてのクラスファイル (JAR ファイルでない) に一致します。末尾が「/*」の codeBase は、そのディレクトリ内にあるすべてのファイル (クラスファイルと JAR ファイルの両方) に一致します。末尾が「/-」の codeBase は、ディレクトリのすべてのファイル (クラスファイルと JAR ファイルの両方)、および再帰的にそのディレクトリのサブディレクトリにあるすべてのファイルを表します。次の表では、さまざまなケースを示します。

ダウンロードされたコードの codebase URL ポリシーの codebase URL 一致するかどうか
java.sun.com/people/gong/ java.sun.com/people/gong
Y
java.sun.com/people/gong/ java.sun.com/people/gong/
Y
java.sun.com/people/gong/ java.sun.com/people/gong/*
Y
java.sun.com/people/gong/ java.sun.com/people/gong/-
Y
java.sun.com/people/gong/appl.jar java.sun.com/people/gong/
N
java.sun.com/people/gong/appl.jar java.sun.com/people/gong/-
Y
java.sun.com/people/gong/appl.jar java.sun.com/people/gong/*
Y
java.sun.com/people/gong/appl.jar java.sun.com/people/-
Y
java.sun.com/people/gong/appl.jar java.sun.com/people/*
N
java.sun.com/people/gong/ java.sun.com/people/-
Y
java.sun.com/people/gong/ java.sun.com/people/*
N

アクセス権エントリ

アクセス権エントリ は、permission で始まります。先に示したテンプレートの permission_class_name の部分には、実際には、java.io.FilePermissionjava.lang.RuntimePermission など、特定のアクセス権型を指定します。

java.io.FilePermission (どのような種類のファイルアクセスを許可するかを指定) など、多くのアクセス権型では、"action" が必須です。java.lang.RuntimePermission など、アクションの指定が必要でないアクセス権型では、"action" を指定する必要はありません。この場合は、permission_class_name のあとの "target_name" 値で指定されたアクセス権が与えられるか、アクセス権が与えられないかのどちらかになります。

アクセス権エントリの signedBy の名前と値のペアは省略可能です。この値が存在する場合は、署名付きアクセス権であることを示します。つまり、そのアクセス権を与えることができるためには、アクセス権クラスそれ自体が、指定された別名によって署名されていなければなりません。たとえば、次のような付与エントリがあるとします。

  grant {
      permission Foo "foobar", signedBy "FooSoft";
  }

この場合、アクセス権 Foo.class がある JAR ファイルに置かれていて、その JAR ファイルが別名 "FooSoft" により指定される証明書に含まれている公開鍵に対応する非公開鍵によって署名されているか、Foo.class がシステムクラスである場合に、このアクセス権型「Foo」が与えられます。システムクラスはポリシーによる制限を受けません。

アクセス権エントリの各項目は、指定の順序 (permissionpermission_class_name、"target_name"、"action"、および signedBy "signer_names") で指定しなければなりません。各エントリはセミコロンで終わります。

識別子 (permissionsignedBycodeBase など) では大文字と小文字は区別されませんが、permission_class_name と、値として引き渡される文字列については大文字と小文字が区別されます。

Win32 システム上でのファイルパスの指定についての注記

注: java.io.FilePermission を指定する場合、"target_name" はファイルパスになります。Win32 システムでは、ファイルパスを codeBase URL ではなく直接文字列で指定する場合は、パス中のバックスラッシュは、次のように 2 つ重ねて指定する必要があります。

  grant {
      permission java.io.FilePermission "C:\\users\\cathy\\foo.bat", "read";
  };
これは、文字列はトークナイザ (java.io.StreamTokenizer) によって処理され、トークナイザは「\」をエスケープ文字列と解釈するため (「\n」は改行を表すなど)、バックスラッシュそのものを表すためには、バックスラッシュを 2 つ重ねなければならないからです。トークナイザは、上記のファイルパス文字列の処理を終えると、二重のバックスラッシュを単一のバックスラッシュに変換し、最終的には次のようになります。
    "C:\users\cathy\foo.bat"

ポリシーファイルの例

ポリシー構成ファイルから取り出した 2 つのエントリの例を次に示します。

  // If the code is signed by "Duke", grant it read/write access to all 
  // files in /tmp:
  grant signedBy "Duke" {
      permission java.io.FilePermission "/tmp/*", "read,write";
  };

  // Grant everyone the following permission:
  grant { 
      permission java.util.PropertyPermission "java.vendor", "read";
  };
 

別のポリシー構成ファイルの例を次に示します。

  grant signedBy "sysadmin", codeBase "file:/home/sysadmin/*" {
      permission java.security.SecurityPermission "Security.insertProvider.*";
      permission java.security.SecurityPermission "Security.removeProvider.*";
      permission java.security.SecurityPermission "Security.setProperty.*";
  };
これは、次の条件を満たすコードだけが Security クラス内のメソッドを呼び出して、プロバイダの追加または削除を行なったり、Security プロパティーを設定したりできることを示しています。

コードソースを指定する要素は、どちらも (または両方を) 省略可能です。codeBase を省略した例を次に示します。

  grant signedBy "sysadmin" {
      permission java.security.SecurityPermission "Security.insertProvider.*";
      permission java.security.SecurityPermission "Security.removeProvider.*";
  };
このポリシーが有効な場合、"sysadmin" によって署名された JAR ファイルに含まれるコードは、JAR ファイルの出所に関係なく、プロバイダの追加と削除が行えます。

署名者を省略した例を次に示します。

  grant codeBase "file:/home/sysadmin/-" {
      permission java.security.SecurityPermission "Security.insertProvider.*";
      permission java.security.SecurityPermission "Security.removeProvider.*";
  };
この場合、ローカルファイルシステムの /home/sysadmin/ ディレクトリに置かれたコードは、プロバイダの追加と削除を行うことができます。コードに署名は必要ありません。

codeBasesignedBy を両方とも省略した例を次に示します。

  grant {
      permission java.security.SecurityPermission "Security.insertProvider.*";
      permission java.security.SecurityPermission "Security.removeProvider.*";
  };
この例では、コードソースを指定する要素がどちらも省略されています。したがって、出所がどこか、署名が付いているか、誰の署名が付いているかに関係なく、どのコードでもプロバイダの追加と削除が行えます。

次の例は、プリンシパルベースのエントリを表しています。

  grant principal javax.security.auth.x500.X500Principal "cn=Alice" {
      permission java.io.FilePermission "/home/Alice", "read, write";
  };
これにより、X500Principal のアクセス権 cn=Alice として実行するコードは /home/Alice を読み取ることも書き込むことも可能になります。

次の例は、codesource 情報と principal 情報を持つ grant 文を表しています。

  grant codebase "http://www.games.com",
        signedBy "Duke",
        principal javax.security.auth.x500.X500Principal "cn=Alice" {
      permission java.io.FilePermission "/tmp/games", "read, write";
  };
これにより、Duke によって署名され、www.games.com からダウンロードされたコードが cn=Alice によって実行されると、/tmp/games ディレクトリへの読み取り権と書き出し権が与えられます。

次の例は、キーストアの別名を置き換える grant 文を示しています。

  keystore "http://foo.bar.com/blah/.keystore";

  grant principal "alice" {
      permission java.io.FilePermission "/tmp/games", "read, write";
  };
"alice" は次のアクセス権に置き換えられます。
javax.security.auth.x500.X500Principal "cn=Alice"
ただし、キーストアの別名 alice に関連付けられた X.509 証明書がサブジェクトの識別名 cn=Alice を持っていることが前提となります。これにより、X500Principal のアクセス権 cn=Alice によって実行されるコードに、/tmp/games ディレクトリへの読み取り権と書き出し権が与えられます。

ポリシーファイルにおけるプロパティーの展開

ポリシーファイルとセキュリティープロパティーファイルでは、プロパティーの展開が可能です。

プロパティーの展開は、シェルにおける変数の展開に似ています。ポリシーファイルまたはセキュリティープロパティーファイルに次のような文字列がある場合、

    ${some.property}
この文字列はシステムプロパティーの値に展開されます。次に例を示します。
    permission java.io.FilePermission "${user.home}", "read";
この場合、"${user.home}" は、システムプロパティー user.home の値に展開されます。user.home の値が /home/cathy である場合、上の記述は下の記述と同じになります。
    permission java.io.FilePermission "/home/cathy", "read";
プラットフォームにより異なるポリシーファイルを使いやすくするために、${/} という特殊な表記 (${file.separator} の簡略形) を使用できます。この表現を使用して、次のような指定が可能です。
    permission java.io.FilePermission "${user.home}${/}*", "read";
user.home プロパティーの値が /home/cathy で、プラットフォームが Solaris である場合、これは次のように変換されます。
    permission java.io.FilePermission "/home/cathy/*", "read";
一方、user.home の値が C:\users\cathy で、プラットフォームが Win32 である場合は、次のように変換されます。
    permission java.io.FilePermission "C:\users\cathy\*", "read";
また、特殊なケースとして、次のようにコードベースのプロパティーを展開する場合は、file.separator 文字は自動的に / に変換されます。
    grant codeBase "file:${java.home}/lib/ext/"
したがって、Win32 システムでは次のように変換されます。
    grant codeBase "file:C:/jdk1.4/jre/lib/ext/"
これは java.homeC:\jdk1.4\jre に設定されている場合も同様です。したがって、コードベース文字列では ${/} を使う必要はありません。また、使うべきではありません。

プロパティーの展開は、ポリシーファイル内で、二重引用符で囲まれた文字列が使用できる場所であればどこでも行われます。プロパティーの展開が行われる場所としては、"signer_names""URL""target_name""action" の各フィールドが挙げられます。

プロパティーの展開が許可されるかどうかは、セキュリティープロパティーファイルの policy.expandProperties プロパティーの値によって決まります。このプロパティーの値が true (デフォルト) の場合は、展開が許可されます。

注:入れ子のプロパティーは使用できません。次に例を示します。

    "${user.${foo}}"
この例では、foo プロパティーが home に設定されている場合であっても、エラーになります。これは、プロパティー構文解析プログラムは入れ子になったプロパティーを認識しないためです。プロパティー構文解析プログラムは、最初の「${」見つけたら、次に最初の「}」を探し、その結果 (この場合は ${user.$foo}) をプロパティーと解釈しようと試みます。しかし、そのようなプロパティーがない場合はエラーになります。

注:付与エントリ、アクセス権エントリ、またはキーストアエントリで展開できないプロパティーがある場合、そのエントリは無視されます。たとえば、次のようにシステムプロパティー foo が定義されていない場合、

    grant codeBase "${foo}" {
        permission ...;
        permission ...;
    };
この grant エントリ内の permission はすべて無視されます。また、次のような場合、
    grant {
        permission Foo "${foo}";
        permission Bar "barTarget";
    };
permission Foo... エントリだけが無視されます。また、次のように指定されている場合、
    keystore "${foo}";
この場合は、keystore エントリが無視されます。

Win32 システム、ファイルパス、およびプロパティーの展開

前述のとおり、Win32 システムでは、ファイルパスを codeBase URL ではなく直接文字列で指定する場合は、パス中のバックスラッシュは、次のように 2 つ重ねて指定する必要があります。
    grant {
        permission java.io.FilePermission "C:\\users\\cathy\\foo.bat", "read";
    };
これは、文字列はトークナイザ (java.io.StreamTokenizer) によって処理され、トークナイザは「\」をエスケープ文字列と解釈するため (たとえば、「\n」は改行を表す)、バックスラッシュそのものを表すためには、バックスラッシュを 2 つ重ねなければならないからです。トークナイザは、上記のファイルパス文字列の処理を終えると、二重のバックスラッシュを単一のバックスラッシュに変換し、最終的には次のようになります。
    "C:\users\cathy\foo.bat"
文字列中のプロパティーの展開は、トークナイザがその文字列の処理を完了したあとに行われます。たとえば、次のような文字列があるとします。
    "${user.home}\\foo.bat"
トークナイザは、この文字列中の二重のバックスラッシュを単一のバックスラッシュに変換し、結果は次のようになります。
    "${user.home}\foo.bat"
次に、${user.home} プロパティーが展開されて次のようになります。
    "C:\users\cathy\foo.bat"
ここでは、user.home の値を C:\users\cathy としています。もちろん、プラットフォームに依存しないために、明示的にスラッシュを使うのではなく、${/} プロパティーを使って次のように指定する方が望ましいと言えます。
    "${user.home}${/}foo.bat"

ポリシーファイルにおける一般的な展開

ポリシーファイルでは一般化された形式の展開もサポートされています。たとえば、アクセス権名が次の形式の文字列を含んでいるとします。
${{protocol:protocol_data}}
このような文字列がアクセス権名に含まれる場合、protocol の値によって実行される展開のタイプが決まり、protocol_data は展開を実行するために使用されます。protocol_data は空にすることもできます。空の場合は、上記の文字列は次のような単純な形式になります。
${{protocol}}

デフォルトのポリシーファイルの実装では、次の 2 つのプロトコルがサポートされます。

  1. ${{self}}

    プロトコル self は、${{self}} 文字列全体を 1 つ以上のプリンシパルクラスとプリンシパル名のペアに置き換えることを示します。実際に実行される置き換えは、permission を含む grant 句によって決まります。

    grant 句にプリンシパルの情報が含まれていない場合は、permission は無視されます。プリンシパルベースの grant 句のコンテキストでは、ターゲット名に ${{self}} を含む permission のみが有効です。たとえば、次の grant 句内の BarPermission は常に無視されます。

    	    grant codebase "www.foo.com", signedby "duke" {
    		permission BarPermission "... ${{self}} ...";
    	    };
    	
    grant 句にプリンシパル情報が含まれている場合は、${{self}} がそのプリンシパル情報に置き換えられます。たとえば、次の grant 句の BarPermission 内の ${{self}} は、javax.security.auth.x500.X500Principal "cn=Duke" に置き換えられます。
    grant principal javax.security.auth.x500.X500Principal "cn=Duke" {
        permission BarPermission "... ${{self}} ...";
    };
    
    grant 句内にコンマで区切られたプリンシパルのリストがある場合、${{self}} は、そのコンマで区切られたプリンシパルのリストに置き換えられます。grant クラス内のプリンシパルクラスとプリンシパル名がどちらもワイルドカードになっている場合、${{self}} は、現在の AccessControlContext 内の Subject に関連付けられたすべてのプリンシパルに置き換えられます。

    次の例は、selfキーストアの別名の置き換えの両方を含む例を示しています。

    keystore "http://foo.bar.com/blah/.keystore";
    
    grant principal "duke" {
        permission BarPermission "... ${{self}} ...";
    };
    
    上の例では、初めに "duke" が、javax.security.auth.x500.X500Principal "cn=Duke" に展開されます。ただし、キーストアの別名「duke」に関連付けられた X.509 証明書がサブジェクトの識別名「cn=Duke」を持っていることが前提となります。次に、${{self}} が、grant 句内で展開されたその同じプリンシパル情報に置き換えられます。javax.security.auth.x500.X500Principal "cn=Duke".

  2. ${{alias:alias_name}}

    プロトコル alias は、java.security.KeyStore 別名の置換を示します。KeyStore エントリ に指定された KeyStore が使用されます。${{alias:alias_name}} は、javax.security.auth.x500.X500Principal "DN" に置き換えられます。DN は、alias_name に属する証明書のサブジェクトの識別名を表します。例を示します。

    keystore "http://foo.bar.com/blah/.keystore";
    
    grant codebase "www.foo.com" {
        permission BarPermission "... ${{alias:duke}} ...";
    };
    
    上の例の別名 duke に関連付けられている X.509 証明書は、キーストア foo.bar.com/blah/.keystore から取得されます。duke の証明書がサブジェクトの識別名として「o=dukeOrg, cn=duke」を指定している場合、${{alias:duke}} は、<javax.security.auth.x500.X500Principal "o=dukeOrg, cn=duke" に置き換えられます。

    次のエラー条件に該当する場合、アクセス権エントリは無視されます。

    • キーストアエントリが指定されていない
    • alias_name が指定されていない
    • alias_name の証明書を取得できない
    • 取得される証明書が X.509 証明書ではない

関連ドキュメント


Copyright © 1997-2002 Sun Microsystems, Inc.All Rights Reserved.

コメントの送付先:java-security@sun.com。これは購読リストではありません。
Sun
Java Software