Java SE JDK のセキュリティーアーキテクチャーはポリシーベースで、きめ細かなアクセス管理が可能です。ロードされたコードには、現在有効なセキュリティーポリシーを基に「アクセス権」が割り当てられます。個々のアクセス権には、特定のリソースに対して許可されるアクセスが指定されます。たとえば、特定のファイルやディレクトリに対する「読み取り」と「書き込み」のアクセスや、特定のホストとポートへの「接続」アクセスなどです。ポリシーは、署名者や場所の異なるコードに与える権限を指定します。ポリシーは、構成可能な外部のポリシーファイルを使って初期化できます。コードに対し明示的にアクセス権が与えられていなければ、そのコードから、そのアクセス権で保護されたリソースにはアクセスできません。アクセス権とポリシーのこの新しい概念により、JDK ではきめ細かで調節しやすく、柔軟で拡張性の高いアクセス管理を提供できます。アプレットだけでなく、アプリケーション、Bean、サーブレットを含むすべての Java コードに、このようなアクセス管理を指定できるようになりました。
Java のセキュリティーアーキテクチャーの詳細については、セキュリティーのドキュメントを参照してください。
SecurityManager
クラスには、名前が check
で始まるメソッドが多数あります。たとえば、checkRead
や checkConnect
などです。Java ライブラリのさまざまなメソッドが、セキュリティーが重視されるオペレーションを実行する前に毎回 check
メソッドを呼び出します。これにより、セキュリティーマネージャーには、例外をスローしてオペレーションの実行を阻止する機会が与えられます。セキュリティーマネージャールーチンは、操作が許可される場合は何も行わずに復帰します。操作が許可されない場合は SecurityException をスローします。ただし、checkTopLevelWindow
はこうした規約の唯一の例外で、boolean 値を返します。
SecurityManager
クラスに含まれる、もうひとつの主要なタイプのメソッドは、クラスローダーの存在と深度に関係するクラスです。
java.lang.SecurityManager
クラスは abstract クラスでした。セキュリティーマネージャーの check
メソッドは、デフォルト実装では例外をスローしました。クラスローダーと深度に関連するクラスは適切に、多くの場合はネイティブコードで実装されました。
セキュリティーマネージャーをインストールしようとするアプリケーション (ブラウザなど) はすべて、独自のセキュリティーマネージャーを作成して、デフォルトで例外をスローするメソッドの固定実装を適切に提供する必要がありました。これらのメソッドは、主に check
メソッドでした。
JDK 1.1 アプレットのセキュリティーマネージャーモデルを基にしたセキュリティーマネージャーは、一般的には次の 2 点に基づいてアクセス管理を決定します。
これらのタイプの決定は、クラスローダーの存在と深度に関係する 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 コードはアプレットから呼び出された場合にも、クラスローダーを作成することができます。その理由は、使用されるのはクラスローダーを持つクラスの深度であり、それが存在するという事実ではないからです。
java.lang.SecurityManager
クラスをアプリケーションのデフォルトのセキュリティーマネージャーとして使用できるよう、多くの変更が加えられました。特に次の点が重要です。
abstract
クラスではなくなったので、そのままインストールすることができる。check
メソッドは、新規作成された checkPermission
メソッドを呼び出す。このメソッドは、デフォルトで、新規作成された AccessController
クラス内の同名のメソッド (checkPermission
) を呼び出す。checkPermission
を呼び出さないメソッドには、適切なデフォルトが設定されている。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 スタイルのセキュリティーマネージャーが動作するように変更されました。
これらのメソッドを次に挙げます。
クラスローダーと深度に関連するメソッドはすべて、次の 3 つの点で修正されました。
ClassLoader.getSystemClassLoader
によって返される) またはその祖先の 1 つに等しいクラスローダーであると定義されます。
システムクラスローダーによってロードされたクラスには、アプリケーションクラス (CLASSPATH
からロードされる)、拡張クラス、組み込み JDK クラスがあるので、これらのメソッドはこの修正により、これらのコードを無視することができます。
カスタムセキュリティーマネージャーをインストールしているアプリケーションを実行する場合で、かつそのセキュリティーマネージャーが JDK の CLASSPATH
からロードされる場合には、そのセキュリティーマネージャーには、システムクラスローダーが関連付けられます。JDK 1.1 ではアプリケーションクラスはクラスローダーを持ちません。ユーザーがカスタムセキュリティーマネージャー内から classLoaderDepth
のようなメソッドを呼び出す予定で、またそのメソッドがシステムクラスローダーによりロードされたクラスを無視するように変更されていない場合には、そのメソッドは常に 0 を返します。これは便利とは言えません。同様に、クラスローダーメソッドがシステムクラスを無視するように変更されておらず、カスタムのセキュリティーマネージャーが CLASSPATH
からロードされる場合にも、たとえば "classLoaderDepth() == 2" のときにオペレーションを許可しないという方法で、セキュリティーマネージャーが決定を行うような場合には、セキュリティーホールが生じます。(実際は "classLoaderDepth() <= 2" であるべきです。)
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
メソッドは、checkPermission
を java.util.PropertyPermission
アクセス権で呼び出します。
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. ... }
次のセクションで、各メソッドをオーバーライドする方法を説明します。
java.lang.SecurityManager
メソッドに加えられた変更のリストを示し、オーバーライドを実行する際のアドバイスを行います。これらのメソッドの詳細については、SecurityManager
クラスの Java ドキュメントを参照してください。
このフィールドは非推奨になり、JDK 内でのこのフィールドの使用はすべて削除されました。inCheck を使う代わりに、checkPermission
を doPrivileged
とともに使ってください。
このメソッドも非推奨になりました。
コンストラクタは、呼び出し元が RuntimePermission("createSecurityManager")
アクセス権を持っていると仮定して、複数の SecurityManager の作成が可能になるように修正されました。
変更はありません。この呼び出しは、JDK で変更されたメソッド (currentClassLoader
、currentLoadedClass
、classLoaderDepth
、inClassLoader
) の 1.1 での動作をエミュレートするために使用できます。
JDK 1.1 スタイルのセキュリティーマネージャーでのこのメソッドの典型的な使用方法は、スタックにクラスローダーがあるかどうかを調べることです。このとき、クラスローダーがない場合は、コードを「信頼できる」ものとして取り扱い、コードにすべての動作を許可します。このメソッドは JDK で修正され、doPrivileged
を呼び出す信頼できる JDK コード (実際には、java.security.AllPermission
を与えられたすべてのコード) は、1.1 スタイルのセキュリティーマネージャーに信頼されるものとして取り扱われるようになりました。またこのコードは、システムクラスローダーを無視するように修正されました。システムクラスローダーとは、システムクラスローダー (ClassLoader.getSystemClassLoader によって返される) またはその祖先の 1 つに等しいクラスローダーであると定義されます。
このメソッドは、次の 3 つの場合に null
を返します。
java.security.AllPermission
アクセス権で呼び出した結果、SecurityException がスローされなかった場合。このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
このメソッドは currentClassLoader
と同様の方法で修正されました。その時点でのセキュリティーコンテキストに AllPermission
が与えられているか、スタック上のすべてのメソッド (存在する場合は、特権を持つ最初の呼び出し元まで) がシステムクラスローダーまたはその上位クラスの 1 つを使って定義されたクラスからのものである場合には、null
を返します。
このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
動作に変更はありません。このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
このメソッドは currentClassLoader
と同様の方法で修正されました。その時点でのセキュリティーコンテキストに AllPermission
が与えられているか、スタック上のすべてのメソッド (存在する場合は、特権を持つ最初の呼び出し元まで) がシステムクラスローダーまたはその上位クラスの 1 つを使って定義されたクラスからのものである場合には、-1
を返します。
このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
動作に変更はありません。このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
このメソッドは、currentClassLoader
が null 以外のクラスローダーを返す場合には、true を返します。そのため、このメソッドは currentClassLoader
と同じセマンティクスに従います。
このメソッドは非推奨になりました。代わりに checkPermission
を使用します。
このメソッドは、java.security.AccessController.getContext
への呼び出しとともに作成された java.security.AccessControlContext
オブジェクトを返します。JDK 1.1 では、このメソッドはデフォルトで null
を返していました。
これは、JDK に新しく追加されたメソッドです。指定されたアクセス権で java.security.AccessController.checkPermission
を呼び出します。内部的には、JDK は直接 AccessController
を呼び出さずに、常に SecurityManager.checkPermission
を呼び出します。このため、プログラマはこのメソッドをオーバーライドして、監査や GUI ダイアログのような機能を追加することができます。
これは、JDK に新しく追加されたメソッドです。context
が AccessControlContext
のインスタンスである場合は、AccessControlContext.checkPermission
メソッドが、指定されたアクセス権に従って呼び出されます。
context
が AccessControlContext
のインスタンスでない場合は、SecurityException
がスローされます。
このメソッドは修正されました。checkPermission
を RuntimePermission("createClassLoader")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkCreateClassLoader
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkCreateClassLoader() { if (someCustomSecurityCheckFails()) { super.checkCreateClassLoader(); } } }
スレッドの引数がシステムスレッド (親が null
であるスレッドグループに属するスレッド) の場合、このメソッドは RuntimePermission("modifyThread")
アクセス権で checkPermission
を呼び出します。
より厳しいポリシーが必要なアプリケーションでは、このメソッドをオーバーライドする必要があります。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドの 1 番目の文で 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")); } ... } }
スレッドグループの引数がシステムスレッドグループ (親が null
) の場合、このメソッドは、RuntimePermission("modifyThreadGroup")
アクセス権で checkPermission
を呼び出します。
より厳しいポリシーが必要なアプリケーションでは、このメソッドをオーバーライドする必要があります。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドの 1 番目の文で 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")); } ... } }
このメソッドは修正されました。checkPermission
を RuntimePermission("exitVM")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkExit
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkExit(int status) { if (someCustomSecurityCheckFails()) { super.checkExit(status); } } }
このメソッドは修正されました。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); } } }
このメソッドは修正されました。checkPermission
を RuntimePermission("loadLibrary."+lib)
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkLink
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkLink(String lib) { if (someCustomSecurityCheckFails()) { super.checkLink(lib); } } }
このメソッドは修正されました。checkPermission
を RuntimePermission("readFileDescriptor")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkRead
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkRead(FileDescriptor fd) { if (someCustomSecurityCheckFails()) { super.checkRead(fd); } } }
このメソッドは修正されました。checkPermission
を FilePermission(file,"read")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkRead
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkRead(String file) { if (someCustomSecurityCheckFails()) { super.checkRead(file); } } }
このメソッドは修正されました。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); } } }
このメソッドは修正されました。checkPermission
を RuntimePermission("writeFileDescriptor")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkWrite
への呼び出しを行う必要があります。例:
public class MySecurityManager extends SecurityManager { public void checkWrite(FileDescriptor fd) { if (someCustomSecurityCheckFails()) { super.checkWrite(fd); } } }
このメソッドは修正されました。checkPermission
を FilePermission(file,"write")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkWrite
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkWrite(String file) { if (someCustomSecurityCheckFails()) { super.checkWrite(file); } } }
このメソッドは修正されました。checkPermission
を FilePermission(file,"delete")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkDelete
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkDelete(String file) { if (someCustomSecurityCheckFails()) { super.checkDelete(file); } } }
このメソッドは修正されました。ポートが -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); } } }
このメソッドは修正されました。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); } } }
このメソッドは修正されました。ポートが 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); } } }
このメソッドは修正されました。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); } } }
このメソッドは修正されました。checkPermission
を SocketPermission(maddr.getHostAddress(),"accept,connect")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkMulticast
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkMultiCast(InetAddress maddr) { if (someCustomSecurityCheckFails()) { super.checkMultiCast(maddr); } } }
このメソッドは修正されました。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); } } }
このメソッドは修正されました。checkPermission
を PropertyPermission("*", "read,write")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkPropertiesAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkPropertiesAccess() { if (someCustomSecurityCheckFails()) { super.checkPropertiesAccess(); } } }
このメソッドは修正されました。checkPermission
を PropertyPermission(key, "read")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkPropertyAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkPropertyAccess(String key) { if (someCustomSecurityCheckFails()) { super.checkPropertiesAccess(key); } } }
このメソッドは修正されました。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; } } }
このメソッドは修正されました。checkPermission
を RuntimePermission("queuePrintJob")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkPrintJobAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkPrintJobAccess() { if (someCustomSecurityCheckFails()) { super.checkPrintJobAccess(); } } }
このメソッドは修正されました。checkPermission
を AWTPermission("accessClipboard")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkSystemClipboardAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkSystemClipboardAccess() { if (someCustomSecurityCheckFails()) { super.checkSystemClipboardAccess(); } } }
このメソッドは修正されました。checkPermission
を AWTPermission("accessEventQueue")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkAwtEventQueueAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkAwtEventQueueAccess() { if (someCustomSecurityCheckFails()) { super.checkAwtEventQueueAccess(); } } }
このメソッドは修正されました。最初に、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(); ... } }
このメソッドは修正されました。最初に、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(); ... } }
このメソッドは修正されました。checkPermission
を RuntimePermission("setFactory")
アクセス権で呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkSetFactory
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkSetFactory() { if (someCustomSecurityCheckFails()) { super.checkSetFactory(); } } }
このメソッドは修正されました。デフォルトのポリシーは 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 で現在でも呼び出し元の深度に基づいている唯一のセキュリティーマネージャーメソッドです。このメソッドが存在する理由は、呼び出し元が、自分と同じクラスローダーからのクラスに反映できるようにするためです。
このメソッドは修正されました。指定されたアクセス権ターゲット名に対する SecurityPermission
オブジェクトを作成し、そのアクセス権で checkPermission
を呼び出します。
このメソッドをオーバーライドする場合は、オーバーライドされたメソッドが通常は例外をスローする位置で、super.checkSecurityAccess
への呼び出しを行う必要があります。たとえば、
public class MySecurityManager extends SecurityManager { public void checkSecurityAccess(String target) { if (someCustomSecurityCheckFails()) { super.checkSecurityAccess(target); } } }
このメソッドは修正されていません。