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 ソフトウェア