環境
コードが非常に厳密なサンドボックスで実行される Java システムを作成しています。クエリ (1 つ以上のクラスで構成される) は、その実行中に、1 つのフォルダー (およびフォルダー内に含まれるサブフォルダーとファイル) へのアクセスのみを許可する必要があります。
、およびクエリ実行ごとSecurityManagerに新しいを使用して、サンドボックスを強制します。usingでClassLoaderクラスを定義するときに、付与する必要があるファイル読み取り権限を含むを渡します。ClassLoaderdefineClassProtectionDomain
コール スタック上のすべてのオブジェクトが必要な特権を持っているわけではないため、クエリの読み取りアクションはAccessController.doPrivileged(...)-block 内で実行されます。
問題
AccessController.checkPermission(...)ブロック内から直接呼び出すと、doPrivileged(...)静かに返されますSystem.getSecurityManager().checkPermission(...)にリクエストを転送する を呼び出すとAccessController、AccessControllerは例外をスローします。- ?を介して
ProtectionDomain呼び出すと、 が失われるようです。AccessControllerSecurityManager - 制限されたファイル アクション ( の作成など) は、ではなく
java.io.FileReaderを直接呼び出します。ブロックを呼び出したクラスのを尊重するために、 を介して呼び出されたときに を取得するにはどうすればよいですか?SecurityManagerAccessControllerAccessControllerSecurityManagerProtectionDomaindoRestricted(...) - 自体に
SecurityManager必要なアクセス許可がない可能性がありますか? これにより、特権コード間の呼び出しスタックに挟まれることで、AccessControllerどれも特権結合を生成しませんか?
以下にサンプル セクションを示します。
AccessController.doPrivileged(new PrivilegedAction<QueryResult>() {
public QueryResult run() {
String location = folderName + "/hello";
FilePermission p = new FilePermission(location, "read");
try {
AccessController.checkPermission(p); // Doesn't raise an exception
System.out.println("AccessController says OK");
System.getSecurityManager().checkPermission(p); // Raises AccessControlException
System.out.println("SecurityManager says OK");
} catch (AccessControlException e) {
System.out.println("### Not allowed to read");
}
return null;
}
});
スタック トレースの一部を含む、プログラムによって生成された出力 (使用される長いパス名を置き換える PATH):
AccessController says OK
Asked for permission: ("java.io.FilePermission" "PATH/hello" "read")
java.security.AccessControlException: access denied ("java.io.FilePermission" "PATH/hello" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
at java.security.AccessController.checkPermission(AccessController.java:560)
at com.aircloak.cloak.security.CloakSecurityManager.checkPermission(CloakSecurityManager.java:40)
at com.dummycorp.queries.ValidQuery$1.run(ValidQuery.java:23)
at com.dummycorp.queries.ValidQuery$1.run(ValidQuery.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at com.dummycorp.queries.ValidQuery.run(ValidQuery.java:16)
at com.aircloak.cloak.security.CloakSecurityManagerTest$1.run(CloakSecurityManagerTest.java:75)
at java.lang.Thread.run(Thread.java:722)
CloakAccessController.checkPermission(...)実装も興味深いかもしれません。次のようになります。
public void checkPermission(Permission perm) {
if (Thread.currentThread().getId() == this.masterThread) {
return;
} else {
System.out.println("Asked for permission: "+perm.toString());
}
AccessController.checkPermission(perm);
}
主に、それを作成したスレッドのセキュリティ制限をバイパスします。
私のjava.policyファイルの内容は、標準の MacOSX システムのものです。非標準的な変更は含まれていないと思います。