java.lang.SecurityManager
をデフォルトのセキュリティマネージャとしてインストールするこのドキュメントでは、JDK のセキュリティマネージャに加えられた変更について説明します。この変更により、アプリケーションのデフォルトのセキュリティマネージャとしてこのセキュリティマネージャを使用できるようになりました。
JDK 1.1 では、ローカルアプリケーションおよび適切にデジタル署名されたアプレットは通常は信頼され、ファイルシステムなどの重要なシステムリソースへの完全なアクセス権を持っていましたが、署名されていないアプレットは信頼されず、限られたりソースにしかアクセスできませんでした。どのリソースへのアクセスを許可するか決める責任は、セキュリティマネージャが負っていました。J2SE Development Kit のセキュリティアーキテクチャはポリシーベースで、きめ細かなアクセス管理が可能です。ロードされたコードには、現在有効なセキュリティポリシーをもとに「アクセス権」が割り当てられます。個々のアクセス権には、特定のリソースに対して許可されるアクセスが指定されます。たとえば、特定のファイルやディレクトリに対する「読み取り」と「書き込み」のアクセスや、特定のホストとポートへの「接続」アクセスなどです。ポリシーは、署名者や場所の異なるコードに与える権限を指定します。ポリシーは、設定可能な外部のポリシーファイルを使って初期化できます。コードに対し明示的にアクセス権が与えられていなければ、そのコードから、そのアクセス権で保護されたリソースにはアクセスできません。アクセス権とポリシーのこの新しい概念により、JDK ではきめ細かで調節しやすく、柔軟で拡張性の高いアクセス管理を提供できます。アプレットだけでなく、アプリケーション、Beans、サーブレットを含むすべての Java コードに、このようなアクセス管理を指定できるようになりました。
Java のセキュリティアーキテクチャの詳細については、セキュリティドキュメントを参照してください。
セキュリティマネージャのメソッド
SecurityManager
クラスには、名前がcheck
で始まるメソッドが多数あります。たとえばcheckRead
やcheckConnect
などです。Java ライブラリのさまざまなメソッドが、セキュリティが重視される操作を実行する前に毎回check
メソッドを呼び出します。これにより、セキュリティマネージャには、例外をスローして操作の実行を阻止する機会が与えられます。セキュリティマネージャのルーチンは、その操作が許可されているときには単に呼び出し元に戻るだけですが、その操作が許可されていないときには SecurityException をスローします。この規則の唯一の例外はcheckTopLevelWindow
で、これはブール値を返します。
SecurityManager
クラスに含まれる、もうひとつの主要なタイプのメソッドは、クラスローダの存在と深度に関係するクラスです。
- currentClassLoader
- currentLoadedClass
- inClassLoader
- classLoaderDepth
JDK 1.1 のセキュリティマネージャ
JDK 1.1 では、java.lang.SecurityManager
クラスは abstract クラスでした。セキュリティマネージャのcheck
メソッドは、デフォルト実装では例外をスローしました。クラスローダと深度に関連するクラスは適切に、多くの場合はネイティブコードで実装されました。セキュリティマネージャをインストールしようとするアプリケーション (ブラウザなど) はすべて、独自のセキュリティマネージャを作成して、デフォルトで例外をスローするメソッドの固定実装を適切に提供する必要がありました。これらのメソッドは、主に
check
メソッドでした。JDK 1.1 アプレットのセキュリティマネージャモデルを基にしたセキュリティマネージャは、一般的には次の 2 点に基づいてアクセス管理を決定します。
- クラスローダを持つクラス (JDK 1.1 のアプレット) がスタック上にあるかどうか
- クラスローダの深度 (クラスローダを使って定義されたクラスメソッドが、スタックのどれくらいの深さで最近発生したか)
これらのタイプの決定は、クラスローダの存在と深度に関係する
SecurityManager
メソッドの呼び出しによって行われていました。たとえば、典型的な 1.1 スタイルのセキュリティマネージャには、次のようなcheckExit
メソッドがあります。public void checkExit(int status) { if (inClassLoader()) { throw new SecurityException(..); } }このような
checkExit
メソッドは、クラスローダを使って定義されたクラス (アプレット) がスタックにあるときはRuntime.exit
の呼び出しを許可しませんでした。これは前者のケースの例で、クラスローダを持つクラスがスタックにあるかどうかをチェックします。後者のケース (クラスローダの深度) の例は、次のようなものです。
public void checkCreateClassLoader() { if (classLoaderDepth() == 2) { throw new SecurityException(); } }このメソッドは、クラスローダの深度が 2 であってはならないことを示しています。つまり、
checkCreateClassLoader
を呼び出したメソッドを呼び出すメソッドは、クラスローダで定義されたクラスにあってはなりません。たとえば、java.lang.ClassLoader
のコンストラクタはcheckCreateClassLoader
を呼び出します。これは、java.lang.ClassLoader
のコンストラクタを呼び出すメソッドが、クラスローダを持っていてはならないことを意味します。したがって、アプレットはクラスローダを直接作成できないことになります。2 つのメソッドはどちらもアプレットの実行を阻止しようとしますが、2 つには大きな違いがあります。前者のケースでは、スタックのどこかにアプレットがあると
checkExit
が例外をスローします。これは、組み込みの JDK コードであっても、アプレットから呼び出された場合には、VM を終了できないことを意味します。後者のケースでは、JDK コードはアプレットから呼び出された場合にも、クラスローダを作成することができます。その理由は、使用されるのはクラスローダを持つクラスの深度であり、それが存在するという事実ではないからです。J2SE Development Kit でのセキュリティマネージャ
JDK では、java.lang.SecurityManager
クラスをアプリケーションのデフォルトのセキュリティマネージャとして使用できるよう、多くの変更が加えられました。特に次の点が重要です。
abstract
クラスではなくなったので、そのままインストールすることができる
- ほとんどの
check
メソッドは、新規作成されたcheckPermission
メソッドを呼び出す。このメソッドは、デフォルトで、新規作成されたAccessController
クラス内の同名のメソッド (checkPermission
) を呼び出す。checkPermission
を呼び出さないメソッドには、適切なデフォルトが設定されている
- クラスローダがスタックにあるかどうかの決定とクラスローダの深度の計算に JDK 1.1 で使用されていたメソッドは、JDK では変更され、
java.security.AllPermission
の与えられたシステムクラスローダとセキュリティコンテキストを無視するようになる
java.lang.SecurityManager
をデフォルトのセキュリティマネージャとしてインストールする
java.lang.SecurityManager
は abstract クラスでなくなったので、デフォルトのセキュリティマネージャとしてインストールして使用できるようになりました。これを行うには、VM を起動するときにシステムプロパティを設定します。java -Djava.security.manager YourApp別の方法として、次のコードを使ってアプリケーションから直接インストールすることもできます。System.setSecurityManager(new SecurityManager());デフォルトのセキュリティマネージャの動作は、ポリシーファイルを変更することによってカスタマイズできます。詳細については、ポリシーファイルのセキュリティガイドを参照してください。クラスローダおよびクラスローダ深度用メソッドの変更
JDK では、クラスローダとクラスローダ深度に関連する
SecurityManager
メソッドは推奨されておらず、どのcheck
メソッドからも呼び出されません。新しいセキュリティマネージャではこれらのメソッドは使用せず、既存のセキュリティマネージャからも削除することをお勧めします。ただし、これらのメソッドは旧バージョンとの互換性のために残されており、JDK でも 1.1 スタイルのセキュリティマネージャが動作するように変更されました。これらのメソッドを次に挙げます。
- currentClassLoader
- currentLoadedClass
- inClassLoader
- classLoaderDepth
クラスローダと深度に関連するメソッドの修正
クラスローダと深度に関連するメソッドはすべて、次の 3 つの点で修正されました。
- これらのメソッドはシステムクラスローダを無視します。システムクラスローダとは、システムクラスローダ (
ClassLoader.getSystemClassLoader
によって返される) またはその祖先のひとつに等しいクラスローダであると定義されます。システムクラスローダによってロードされたクラスには、アプリケーションクラス (
CLASSPATH
からロードされる)、拡張クラス、組み込み JDK クラスがあるので、これらのメソッドはこの修正により、これらのコードを無視することができます。
カスタムセキュリティマネージャをインストールしているアプリケーションを実行する場合で、かつそのセキュリティマネージャが JDK の
CLASSPATH
からロードされる場合には、そのセキュリティマネージャには、システムクラスローダが関連付けられます。JDK 1.1 ではアプリケーションクラスはクラスローダを持ちません。ユーザがカスタムセキュリティマネージャ内からclassLoaderDepth
のようなメソッドを呼び出す予定で、またそのメソッドがシステムクラスローダによりロードされたクラスを無視するように変更されていない場合には、そのメソッドは常に 0 を返します。これは便利とはいえません。同様に、クラスローダメソッドがシステムクラスを無視するように変更されておらず、カスタムのセキュリティマネージャがCLASSPATH
からロードされる場合にも、たとえば「classLoaderDepth() == 2」のときに操作を許可しないという方法で、セキュリティマネージャが決定を行うような場合には、セキュリティホールが生じます(実際は「classLoaderDepth() <= 2」であるべき)。
- これらのメソッドは、スタック上で「特権付き」のマークがつけられているメソッドに到達すると、チェックを終了します(java.security.AccessController.doPrivileged() および「特権ブロックのための API」を参照)。
- これらのメソッドは、
AllPermission
が与えられているセキュリティコンテキストを、スタック上にクラスローダが存在しないかのように取り扱います。1 番目と 2 番目の変更の例として、JDK でセキュリティマネージャのインストール後にファイルを開くなどの操作を行う場所があります。1.1 スタイルのセキュリティマネージャには、次のような
checkRead
メソッドを持つものがあります。public void checkRead(String file) { if (inClassLoader()) { throw new SecurityException(..); } }JDK のコードを修正しないと、JDK 自体がファイルを読み込もうとしたときに、システムクラスローダでないクラスローダがスタック上に存在する場合には、JDK で実行するようなチェックがセキュリティ例外を引き起こします。新しいセキュリティモデルでは、呼び出し元に対して許可されていない可能性のある操作を実行しようとする JDK コードはすべて、
doPrivileged
ブロックを持ちます。inClassLoader
は単に、「特権付き」コードを含むフレームまでのスタックを調べるだけであり、スタックの一番上のコードはシステムクラスローダまたはその上位クラスによりロードされる JDK コードなので、inClassLoader
メソッドはfalse
を返し、読み取りを許可します。クラスローダ深度の維持
先に説明したように、1.1 アプレットのセキュリティマネージャを基にしたセキュリティマネージャは、アクセス管理の決定の一部をクラスローダ深度に基づいて行います。例として、前述した
checkCreateClassLoader
メソッドをもう一度示します。public void checkCreateClassLoader() { if (classLoaderDepth() == 2) { throw new SecurityException(); } }JDK では、1.1 スタイルのセキュリティマネージャで使用されていたとおりに、スタック深度を維持しようとしました。たとえば、java.security.SecureClassLoader
のコンストラクタは、そのスーパークラス (ClassLoader
) のコンストラクタが同じことを行うとしても、SecurityManager.checkCreateClassLoader
への明示的な呼び出しを行います。SecureClassLoader
のコンストラクタにチェック機能がない場合は、クラスローダの深度は常に 2 よりも大きいため、1.1 スタイルのセキュリティマネージャは信頼されないクラスに対してSecureClassLoader
を拡張してクラスローダを構築することを許可します。
セキュリティマネージャを JDK 環境で実行する前に、まず自分のカスタムセキュリティマネージャのメソッドをすべて解析しておくことを強くお勧めします。解析を行わないと、セキュリティホールが生じたり、JDK が適切に動作しなくなることがあります。これは、1.1 スタイルのセキュリティマネージャが弱い性質を持っているためです。
可能なら、1.2 の
SecurityManager
のデフォルト実装を使うようにします。これは、ユーザと管理者に対して一貫性のある動作を提供するのに役立ちます。これが不可能なら、少なくともcheckXXX
メソッドの中でセキュリティ例外をスローする前にsuper.checkXXX
を呼び出すようにしてください。これにより、アクセス管理アルゴリズムの使用が可能になり、JDK 自体が正しく機能するようになります。JDK では、
SecurityManager check
メソッドの呼び出しに使用されていた既存のコードは、変更されていません。セキュリティチェックの必要な新しいコードについては、呼び出しがSecurityManager.checkPermission
に対して行われ、新しいSecurityManager check
メソッドは追加されません。たとえば、新しく追加されたjava.lang.System.setProperty
メソッドは、java.util.PropertyPermission
アクセス権でcheckPermission
を呼び出します。
SecurityManager
クラスを拡張して既存のメソッドをオーバーライドする場合は、注意が必要です。たとえば、checkRead(String file)
メソッドをオーバーライドして常にセキュリティ例外をスローするようにすると、JDK 自体が正しく動作しなくなることがあります。つまり、一部の JDK コードでファイルを開く必要がある場合に (プロパティファイルの読み込みや、JAR ファイルのロードなどのため)、読み取りのたびにセキュリティ例外をスローすると、ファイルを開く操作が必ず失敗することになります。一般に、デフォルトのメソッドをオーバーライドするのは、セキュリティの緩和の目的でのみ行うべきであり、セキュリティの強化の目的には行うべきではありません。セキュリティを強化したい場合には、デフォルトのポリシーファイルの修正、またはカスタムの
java.security.Policy
オブジェクトのインストールのどちらかまたは両方を行います。詳細については、ポリシーファイルのセキュリティガイドを参照してください。一般に、セキュリティマネージャのメソッドをオーバーライドするときは、オーバーライドされた
super.checkXXX
メソッドが例外をスローする位置に、checkXXX
メソッドへの呼び出しを記述する必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkRead(String file) { if (someCustomSecurityCheckFails()) { super.checkRead(file); } } }カスタムのセキュリティチェックが失敗した場合には、次にsuper.checkRead
が呼び出されます。checkRead
のデフォルト実装ではcheckPermission
が呼び出され、これはデフォルトでAccessController
に問い合わせを行います。AccessController
を呼び出すことにより、ファイルを読み出す前にAccessController.doPrivileged
を行なったシステムコードは、そのファイルの読み取りに成功します。それ以外のすべてのコードはその時点で有効なポリシーに従い、そのファイルへのアクセス権が与えられていない場合には、アクセス管理例外がスローされます。
checkXXX
メソッドには、それをオーバーライドするときにsuper.checkXXX
メソッドを呼び出してはならないものがあります。その理由は、これらのメソッドのデフォルト実装は、オーバーライド後のメソッドで実装しているポリシーほど厳しくない場合があるからです。たとえば、デフォルトのcheckAccess(ThreadGroup g)
メソッドは、システムスレッドグループだけを保護します。独立したスレッドグループ (アプレットスレッドグループなど) をお互いから保護しようとする場合は、通常はセキュリティ例外をスローする位置でsuper.checkAccess
を呼び出すと、カスタムチェックの目的が損なわれるため、通常その位置ではスローしません。その代わり、オーバーライドしたメソッドの最初のステートメントで、super.checkAccess
への呼び出しを記述することができます。次に例を示します。
public class AppletSecurityManager extends SecurityManager { public void checkAccess(ThreadGroup g) { // a call to super will throw an exception if someone // is trying to modify the system thread group super.checkAccess(g); ... // now perform checks based on which applet thread group // the current caller is in to see if they can modify thread group g. ... }次に、各メソッドをオーバーライドする方法を説明します。
ここでは、JDK でjava.lang.SecurityManager
メソッドに加えられた変更のリストを示し、オーバーライドを実行する際のアドバイスを行います。これらのメソッドの詳細については、SecurityManager
クラスの Java ドキュメントを参照してください。protected boolean inCheck
このフィールドは推奨されなくなり、JDK 内でのこのフィールドの使用はすべて削除されました。inCheck を使う代わりに、
checkPermission
をdoPrivileged
とともに使ってください。public boolean getInCheck();
このメソッドも推奨されなくなりました。
public SecurityManager();
コンストラクタは、呼び出し元が
RuntimePermission("createSecurityManager")
アクセス権を持っていると仮定して、複数の SecurityManager の作成が可能になるように修正されました。protected native Class[] getClassContext();
変更はありません。この呼び出しは、JDK で変更されたメソッド (
currentClassLoader
、currentLoadedClass
、classLoaderDepth
、inClassLoader
) の 1.1 での動作をエミュレートするために使用できます。protected ClassLoader currentClassLoader();
JDK 1.1 スタイルのセキュリティマネージャでのこのメソッドの典型的な使用方法は、スタックにクラスローダがあるかどうかを調べることです。このとき、クラスローダがない場合は、コードを「信頼できる」ものとして取り扱い、コードにすべての動作を許可します。このメソッドは JDK で修正され、
doPrivileged
を呼び出す信頼できる JDK コード (実際には、java.security.AllPermission
を与えられたすべてのコード) は、1.1 スタイルのセキュリティマネージャに信頼されるものとして取り扱われるようになりました。またこのコードは、システムクラスローダを無視するように修正されました。システムクラスローダとは、システムクラスローダ (ClassLoader.getSystemClassLoader によって返される) またはその上位オブジェクトのひとつに等しいクラスローダであると定義されます。このメソッドは、次の 3 つの場合に
null
コードを返します。
- 実行スタック上のすべてのメソッドが、システムクラスローダまたはその上位オブジェクトの 1 つを使って定義されたクラスからのものである場合
- 最初の「特権付き」呼び出し元 (java.security.AccessController.doPrivileged を参照) までの実行スタック上のすべてのメソッドが、システムクラスローダまたはその上位オブジェクトの 1 つを使って定義されたクラスからのものである場合
- checkPermission を
java.security.AllPermission
アクセス権で呼び出した結果、SecurityExeception がスローされなかった場合このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。protected Class currentLoadedClass();
このメソッドは
currentClassLoader
と同様の方法で修正されました。その時点でのセキュリティコンテキストにAllPermission
が与えられているか、スタック上のすべてのメソッド (存在する場合は、特権を持つ最初の呼び出し元まで) がシステムクラスローダまたはその上位クラスの 1 つを使って定義されたクラスからのものである場合には、null
を返します。このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。protected int classDepth(String name);
動作に変更はありません。このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。protected int classLoaderDepth();
このメソッドは
currentClassLoader
と同様の方法で修正されました。その時点でのセキュリティコンテキストにAllPermission
が与えられているか、スタック上のすべてのメソッド (存在する場合は、特権を持つ最初の呼び出し元まで) がシステムクラスローダまたはその祖先の 1 つを使って定義されたクラスからのものである場合には、-1
を返します。このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。protected boolean inClass(String name);
動作に変更はありません。このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。protected boolean inClassLoader();
このメソッドは、
currentClassLoader
が null 以外のクラスローダを返す場合には、true を返します。そのため、このメソッドはcurrentClassLoader
と同じセマンティクスに従います。このメソッドは推奨されなくなりました。代わりに
checkPermission
を使用してください。public Object getSecurityContext();
このメソッドは、
java.security.AccessController.getContext
への呼び出しとともに作成されたjava.security.AccessControlContext
オブジェクトを返します。JDK 1.1 では、このメソッドはデフォルトでnull
を返していました。public void checkPermission(Permission perm);
これは、JDK に新しく追加されたメソッドです。指定されたアクセス権で
java.security.AccessController.checkPermission
を呼び出します。内部的には、JDK は直接AccessController
を呼び出さずに、常にSecurityManager.checkPermission
を呼び出します。このため、プログラマはこのメソッドをオーバーライドして、監査や GUI ダイアログのような機能を追加することができます。public void checkPermission(Permission perm, Object context);
これは、JDK に新しく追加されたメソッドです。
context
がAccessControlContext
のインスタンスである場合は、AccessControlContext.checkPermission
メソッドが、指定されたアクセス権に従って呼び出されます。
context
がAccessControlContext
のインスタンスでない場合は、SecurityException
がスローされます。public void checkCreateClassLoader();
このメソッドは修正されました。
checkPermission
をRuntimePermission("createClassLoader")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkCreateClassLoader
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkCreateClassLoader() { if (someCustomSecurityCheckFails()) { super.checkCreateClassLoader(); } } }public void checkAccess(Thread t);
スレッドの引数がシステムスレッド (親が
null
であるスレッドグループに属するスレッド) の場合、このメソッドはRuntimePermission("modifyThread")
アクセス権でcheckPermission
を呼び出します。より厳しいポリシーが必要なアプリケーションでは、このメソッドをオーバーライドする必要があります。
このメソッドをオーバーライドする場合は、オーバーライド後のメソッドの最初のステートメントで
super.checkAccess
メソッドを呼び出すか、同様のセキュリティチェックを行う必要があります。このメソッドをオーバーライドする場合は、オーバーライド後のメソッドでは、呼び出し元のスレッドが
RuntimePermission("modifyThread")
アクセス権を持つかどうかをチェックして、持っている場合には何もせずに終了するようにします。これは、そのアクセス権を与えられたコード (JDK 自体など) がどんなスレッドでも扱えるようにするためです。次に例を示します。
public class MySecurityManager extends SecurityManager { public void checkAccess(Thread t) { // a call to super will throw an exception if someone // is trying to modify a system thread super.checkAccess(t); ... if (someCustomSecurityCheckForOtherThreadsFails()) { // if the check fails, instead of throwing an exception, // call checkPermission, which will throw an exception // if need be checkPermission(new RuntimePermission("modifyThread")); } ... } }public void checkAccess(ThreadGroup g);
スレッドグループの引数がシステムスレッドグループ (親が
null
) の場合、このメソッドは、RuntimePermission("modifyThreadGroup")
アクセス権でcheckPermission
を呼び出します。より厳しいポリシーが必要なアプリケーションでは、このメソッドをオーバーライドする必要があります。
このメソッドをオーバーライドする場合は、オーバーライド後のメソッドの最初のステートメントで
super.checkAccess
メソッドを呼び出すか、同様のセキュリティチェックを行う必要があります。このメソッドをオーバーライドする場合は、オーバーライド後のメソッドでは、呼び出し元のスレッドが
RuntimePermission("modifyThreadGroup")
アクセス権を持つかどうかをチェックして、持っている場合には何もせずに終了するようにします。これは、そのアクセス権を与えられたコード (JDK 自体など) がどんなスレッドグループでも扱えるようにするためです。次に例を示します。
public class MySecurityManager extends SecurityManager { public void checkAccess(ThreadGroup g) { // a call to super will throw an exception if someone // is trying to modify the system thread group super.checkAccess(g); ... if (someCustomSecurityCheckForOtherThreadGroupsFails()) { // if the check fails, instead of throwing an exception, // call checkPermission, which will throw an exception // if need be checkPermission(new RuntimePermission("modifyThreadGroup")); } ... } }public void checkExit(int status);
このメソッドは修正されました。
checkPermission
をRuntimePermission("exitVM")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkExit
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkExit(int status) { if (someCustomSecurityCheckFails()) { super.checkExit(status); } } }public void checkExec(String cmd);
このメソッドは修正されました。
checkPermission
をFilePermission
で呼び出します。cmd
が絶対パス (java.io.File.isAbsolute
を参照) の場合は、FilePermission
のターゲットとしてそのまま渡されます。cmd
が絶対パスでない場合は、特別なターゲット「<<ALL FILES>>」が使用されます。このターゲットを使用する理由は、個別のプラットフォームで実行されるコマンドの実際のパスを判断するのは、環境変数などの要因のために困難なためです。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkExec
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkExec(String cmd) { if (someCustomSecurityCheckFails()) { super.checkExec(cmd); } } }public void checkLink(String lib);
このメソッドは修正されました。
checkPermission
をRuntimePermission("loadLibrary."+lib)
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkLink
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkLink(String lib) { if (someCustomSecurityCheckFails()) { super.checkLink(lib); } } }public void checkRead(FileDescriptor fd);
このメソッドは修正されました。
checkPermission
をRuntimePermission("readFileDescriptor")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkRead
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkRead(FileDescriptor fd) { if (someCustomSecurityCheckFails()) { super.checkRead(fd); } } }public void checkRead(String file);
このメソッドは修正されました。
checkPermission
をFilePermission(file,"read")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkRead
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkRead(String file) { if (someCustomSecurityCheckFails()) { super.checkRead(file); } } }public void checkRead(String file, Object context);
このメソッドは修正されました。
context
がAccessControlContext
のインスタンスである場合は、AccessControlContext.checkPermission
メソッドが、FilePermission(file,"read")
のアクセス権に従って呼び出されます。
context
がAccessControlContext
のインスタンスでない場合は、SecurityException
がスローされます。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkRead
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkRead(String file, Object context) { if (someCustomSecurityCheckFails()) { super.checkRead(file, context); } } }public void checkWrite(FileDescriptor fd);
このメソッドは修正されました。
checkPermission
をRuntimePermission("writeFileDescriptor")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkWrite
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkWrite(FileDescriptor fd) { if (someCustomSecurityCheckFails()) { super.checkWrite(fd); } } }public void checkWrite(String file);
このメソッドは修正されました。
checkPermission
をFilePermission(file,"write")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkWrite
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkWrite(String file) { if (someCustomSecurityCheckFails()) { super.checkWrite(file); } } }public void checkDelete(String file);
このメソッドは修正されました。
checkPermission
をFilePermission(file,"delete")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkDelete
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkDelete(String file) { if (someCustomSecurityCheckFails()) { super.checkDelete(file); } } }public void checkConnect(String host, int port);
このメソッドは修正されました。ポートが -1 でない場合には、
checkPermission
をSocketPermission(host+":"+port,"connect")
アクセス権で呼び出します。ポートが -1 の場合は、checkPermission
をSocketPermission(host,"resolve")
アクセス権で呼び出します。この動作には JDK 1.1 との一貫性があり、ポートが -1 である場合は、IP アドレスのルックアップが行われていることを示します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkConnect
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkConnect(String host, int port) { if (someCustomSecurityCheckFails()) { super.checkConnect(host, port); } } }public void checkConnect(String host, int port, Object context);
このメソッドは修正されました。
context
がAccessControlContext
のインスタンスである場合は、ポートが -1 に等しくないときには、AccessControlContext.checkPermission
メソッドがSocketPermission(host+":"+port,"connect")
アクセス権で呼び出されます。ポートが -1 に等しいときは、checkPermission
がSocketPermission(host,"resolve")
のアクセス権に従って呼び出されます。
context
がAccessControlContext
のインスタンスでない場合は、SecurityException
がスローされます。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkConnect
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkConnect(String host, int port, Object context) { if (someCustomSecurityCheckFails()) { super.checkConnect(host, port, context); } } }public void checkListen(int port)
このメソッドは修正されました。ポートが 0 でない場合は、
checkPermission
をSocketPermission("localhost:"+port,"listen")
で呼び出します。ポートが 0 の場合は、checkPermission
をSocketPermission("localhost:1024-","listen")
で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkListen
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkListen(int port) { if (someCustomSecurityCheckFails()) { super.checkListen(port); } } }public void checkAccept(String host, int port);
このメソッドは修正されました。
checkPermission
をSocketPermission(host+":"+port,"accept")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkAccept
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkAccept(String host, int port) { if (someCustomSecurityCheckFails()) { super.checkAccept(host, port); } } }public void checkMulticast(InetAddress maddr);
このメソッドは修正されました。
checkPermission
をSocketPermission(maddr.getHostAddress(),"accept,connect")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkMulticast
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkMultiCast(InetAddress maddr) { if (someCustomSecurityCheckFails()) { super.checkMultiCast(maddr); } } }public void checkMulticast(InetAddress maddr, byte ttl);
このメソッドは修正されました。
checkPermission
をSocketPermission(maddr.getHostAddress(),"accept,connect")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkMulticast
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkMultiCast(InetAddress maddr, byte ttl) { if (someCustomSecurityCheckFails()) { super.checkMultiCast(maddr, ttl); } } }public void checkPropertiesAccess();
このメソッドは修正されました。
checkPermission
をPropertyPermission("*", "read,write")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkPropertiesAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkPropertiesAccess() { if (someCustomSecurityCheckFails()) { super.checkPropertiesAccess(); } } }public void checkPropertyAccess(String key);
このメソッドは修正されました。
checkPermission
をPropertyPermission(key, "read")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkPropertyAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkPropertyAccess(String key) { if (someCustomSecurityCheckFails()) { super.checkPropertiesAccess(key); } } }public boolean checkTopLevelWindow(Object window);
このメソッドは修正されました。
checkPermission
をAWTPermission("showWindowWithoutWarningBanner")
アクセス権で呼び出し、SecurityException がスローされない場合は true を返します。それ以外の場合は false を返します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常 false を返す位置で、
super.checkTopLevelWindow
への呼び出しを行い、super.checkTopLevelWindow
の値を返す必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkTopLevelWindow(Object window) { if (someCustomSecurityCheckFails()) { return super.checkTopLevelWindow(window); } else { return true; } } }public void checkPrintJobAccess();
このメソッドは修正されました。
checkPermission
をRuntimePermission("queuePrintJob")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkPrintJobAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkPrintJobAccess() { if (someCustomSecurityCheckFails()) { super.checkPrintJobAccess(); } } }public void checkSystemClipboardAccess();
このメソッドは修正されました。
checkPermission
をAWTPermission("accessClipboard")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkSystemClipboardAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkSystemClipboardAccess() { if (someCustomSecurityCheckFails()) { super.checkSystemClipboardAccess(); } } }public void checkAwtEventQueueAccess();
このメソッドは修正されました。
checkPermission
をAWTPermission("accessEventQueue")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkAwtEventQueueAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkAwtEventQueueAccess() { if (someCustomSecurityCheckFails()) { super.checkAwtEventQueueAccess(); } } }public void checkPackageAccess(String pkg);
このメソッドは修正されました。最初に、
java.security.Security.getProperty("package.access")
を呼び出してコンマで区切られたリストを取得することにより、制限付きのパッケージのリストを得ます。次に、pkg
が制限付きパッケージのどれかで開始するかどうか、または等しいかどうかをチェックします。該当する場合には、checkPermission
がRuntimePermission("accessClassInPackage."+pkg)
アクセス権で呼び出されます。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドの 1 行目で、
super.checkPackageAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkPackageAccess(String pkg) { super.checkPackageAccess(pkg); ... someCustomSecurityCheck(); ... } }public void checkPackageDefinition(String pkg);
このメソッドは修正されました。最初に、
java.security.Security.getProperty("package.definition")
を呼び出してコンマで区切られたリストを取得することにより、制限付きのパッケージのリストを得ます。次に、pkg
が制限付きパッケージのどれかで開始するかどうか、または等しいかどうかをチェックします。該当する場合には、checkPermission
がRuntimePermission("defineClassInPackage."+pkg)
アクセス権で呼び出されます。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドの 1 行目で、
super.checkPackageDefinition
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkPackageDefinition(String pkg) { super.checkPackageDefinition(pkg); ... someCustomSecurityCheck(); ... } }public void checkSetFactory();
このメソッドは修正されました。
checkPermission
をRuntimePermission("setFactory")
アクセス権で呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkSetFactory
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkSetFactory() { if (someCustomSecurityCheckFails()) { super.checkSetFactory(); } } }public void checkMemberAccess(Class clazz, int which);
このメソッドは修正されました。デフォルトのポリシーは PUBLIC メンバへのアクセスおよび、呼び出し元と同じクラスローダを持つクラスへのアクセスを許可します。それ以外の場合はすべて、
checkPermission
がRuntimePermission("accessDeclaredMembers")
アクセス権で呼び出されます。このメソッドをオーバーライドする場合は、
super.checkMemberAccess
への呼び出しは行えません。checkMemberAccess
のデフォルト実装は、スタック深度 4 にあることをチェックされるコードに依存します。次に例を示します。someCaller[3] java.lang.Class.someReflectionAPI [2] java.lang.Class.checkMemberAccess [1] SecurityManager.checkMemberAccess [0]この動作をエミュレートするには、getClassContext
を呼び出し、デフォルトのcheckMemberAccess
メソッドの場合と同様に、インデックス 3 のクラスのクラスローダを調べる必要があります。if (which != Member.PUBLIC) { Class stack[] = getClassContext(); /* * stack depth of 4 should be the caller of one of the * methods in java.lang.Class that invoke checkMember * access.The stack should look like: * * someCaller [3] * java.lang.Class.someReflectionAPI [2] * java.lang.Class.checkMemberAccess [1] * MySecurityManager.checkMemberAccess [0] * */ if ((stack.length<4) || (stack[3].getClassLoader() != clazz.getClassLoader())) { if (checkMemberAccessPermission == null) checkMemberAccessPermission = new RuntimePermission("accessDeclaredMembers"); checkPermission(checkMemberAccessPermission); } }このメソッドは、JDK で現在でも呼び出し元の深度に基づいている唯一のセキュリティマネージャメソッドです。このメソッドが存在する理由は、呼び出し元が、自分と同じクラスローダからのクラスに反映できるようにするためです。
public void checkSecurityAccess(String target);
このメソッドは修正されました。指定されたアクセス権ターゲット名に対する
SecurityPermission
オブジェクトを作成し、そのアクセス権でcheckPermission
を呼び出します。このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、
super.checkSecurityAccess
への呼び出しを行う必要があります。次に例を示します。public class MySecurityManager extends SecurityManager { public void checkSecurityAccess(String target) { if (someCustomSecurityCheckFails()) { super.checkSecurityAccess(target); } } }public ThreadGroup getThreadGroup();
このメソッドは修正されていません。
Copyright © 1997-2001 Sun Microsystems, Inc.All Rights Reserved.
コメントの送付先: java-security@sun.com。これは購読リストではありません。
Java ソフトウェア