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

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

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

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

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

デフォルトの Policy の実装
ポリシーファイルのデフォルトの場所
ポリシーの実装の変更
ポリシーファイルの構文
ポリシーファイルの例
ポリシーファイルでのプロパティーの展開
ポリシーファイルでの一般的な展開
関連項目

デフォルトの Policy の実装

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

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

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

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

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

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

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

java.home/lib/security/java.policy  (Solaris/Linux)
java.home\lib\security\java.policy  (Windows)

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

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

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

user.home/.java.policy  (Solaris/Linux)
user.home\.java.policy  (Windows)

注: user.home は「user.home」という名前のシステムプロパティーの値で、ユーザーのホームディレクトリを指定します。

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

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

java.home/lib/security/java.security  (Solaris/Linux)
java.home\lib\security\java.security  (Windows)
前述のように、java.home は実行環境の格納先ディレクトリ (JDK の jre ディレクトリ、または JRE の最上位ディレクトリ) を指します。ポリシーファイルの場所は、次のような形式の名前を持つプロパティーの値として指定されています。
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 です。指定されたポリシーファイルは、セキュリティープロパティーファイルで指定されたすべてのポリシーファイルに追加されてロードされます。

注:

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

    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 コマンドのどちらの場合も) 無視されます。デフォルトは true です。

ポリシーの実装の変更

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

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

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

    policy.provider=PolicyClassName

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

    policy.provider=sun.security.provider.PolicyFile

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

    policy.provider=com.mycom.MyPolicy

ポリシーファイルの構文

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

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

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

キーストアエントリ

キーストアは、非公開鍵と、対応する公開鍵を認証する X.509 証明書チェーンなどのデジタル証明書が格納されたデータベースです。キーストアの作成と管理には、keytool ユーティリティー (Solaris/Linux 用) (Windows 用) を使います。ポリシー構成ファイルで指定されているキーストアは、そのファイルの 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.example.com/fum/some.policy
また、このポリシーファイルには、次のエントリがあるとします。
    keystore ".keystore";
この場合、キーストアは次の場所からロードされます。
    http://foo.example.com/fum/.keystore
URL に絶対位置を指定することもできます。

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

付与エントリ

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

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

  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 クラスに一致させることができます。さらに、principal_name にワイルドカード値 (*) を設定することで、任意の Principal 名に一致させることができます。principal_class_name または principal_name に * を設定するときは、* を引用符で囲まないでください。また、ワイルドカードのプリンシパルクラスを指定する場合は、ワイルドカードのプリンシパル名も指定する必要があります。

プリンシパルフィールドは省略可能です。省略した場合は、「任意のプリンシパル」という意味になります。

キーストアの別名の置き換えに関するメモ:

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

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

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

    grant codeBase "file:/C:/somepath/api/" {
        ...
    };
codeBase 値の正確な意味は、末尾の文字によって異なります。末尾が「/」の codeBase は、指定されたディレクトリ内のすべてのクラスファイル (JAR ファイルを除く) を示します。末尾が「/*」の codeBase は、そのディレクトリ内にあるすべてのファイル (クラスファイルと JAR ファイルの両方) を示します。末尾が「/-」の codeBase は、指定されたディレクトリとその下の全サブディレクトリ内のすべてのファイル (クラスファイルと JAR ファイルの両方) を示します。次の表では、さまざまなケースを示します。
ダウンロードされたコードの codebase URL ポリシーの codebase URL 一致するかどうか
www.example.com/people/gong/ www.example.com/people/gong Y
www.example.com/people/gong/ www.example.com/people/gong/ Y
www.example.com/people/gong/ www.example.com/people/gong/* Y
www.example.com/people/gong/ www.example.com/people/gong/- Y
www.example.com/people/gong/appl.jar www.example.com/people/gong/ N
www.example.com/people/gong/appl.jar www.example.com/people/gong/- Y
www.example.com/people/gong/appl.jar www.example.com/people/gong/* Y
www.example.com/people/gong/appl.jar www.example.com/people/- Y
www.example.com/people/gong/appl.jar www.example.com/people/* N
www.example.com/people/gong/ www.example.com/people/- Y
www.example.com/people/gong/ www.example.com/people/* N

アクセス権エントリ

アクセス権エントリは、単語 permission で始まります。前述のテンプレートにある単語 permission_class_name は、実際には java.io.FilePermissionjava.lang.RuntimePermission などの特定のアクセス権タイプになります。

java.io.FilePermission (どのような種類のファイルアクセスを許可するかを指定) など、多くのアクセス権タイプでは "action" が必須です。java.lang.RuntimePermission などのカテゴリでは不要なため、必須ではありません。その場合は、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 と、値として引き渡される文字列については大文字と小文字が区別されます。

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

注: java.io.FilePermission を指定する場合、"target_name" はファイルパスになります。Windows システムでは、ファイルパスを 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" を読み取ることも書き込むことも可能になります。

次の例は、ワイルドカード値を含むプリンシパルベースのエントリを表しています。

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

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

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

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

  keystore "http://foo.example.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" の値に展開されます。そのプロパティーの値が "/home/cathy" である場合、上の記述は下の記述と同じになります
    permission java.io.FilePermission "/home/cathy", "read";
プラットフォームにより異なるポリシーファイルを使いやすくするために、"${/}" という特殊な表記 ("${file.separator}" の簡略形) も使用できます。この表現を使用して、次のような指定が可能です。
    permission java.io.FilePermission "${user.home}${/}*", "read";
"user.home" プロパティーの値が /home/cathy で、プラットフォームが Solaris/Linux である場合、これは次のように変換されます。
    permission java.io.FilePermission "/home/cathy/*", "read";
Windows システムで、"user.home" の値が C:\users\cathy であれば、次のように変換されます。
    permission java.io.FilePermission "C:\users\cathy\*", "read";
特殊なケースとして、コードベースのプロパティーを次のように記述すると、
    grant codeBase "file:${java.home}/lib/ext/"
file.separator 文字は自動的に / に変換されます。したがって、Windows システムでは次のように変換されます。
    grant codeBase "file:C:/jdk1.4/jre/lib/ext/"
これは "java.home" が C:\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 エントリが無視されます。

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

前述のとおり、Windows システムでは、ファイルパスを 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.example.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.example.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_name は、KeyStore の別名を表します。${{alias:alias_name}} は、javax.security.auth.x500.X500Principal "DN" に置き換えられます。DN は、alias_name に属する証明書のサブジェクトの識別名を表します。たとえば、

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

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

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

関連項目


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