2 回答

TA貢獻1813條經驗 獲得超2個贊
首先,SecurityManager 有一個受保護的方法getClassContext()。
您的代碼如下所示:
System.setSecurityManager(new SecurityManager() {
? ? public void checkPermission(Permission permission) {
? ? ? ? Class<?> caller = getClassContext()[1];
? ? ? ? ClassLoader ccl = caller.getClassLoader();
? ? ? ? if (ccl != null || ccl != getClass().getClassLoader()) {
? ? ? ? ? ? throw new SecurityException("You do not have permissions.");
? ? ? ? }
? ? }
});
其次,如果要使用 a StackWalker,建議您復用StackWalker實例:
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
System.setSecurityManager(new SecurityManager() {
? ? public void checkPermission(Permission permission) {
? ? ? ? Class<?> caller = walker.getCallerClass();
? ? ? ? ClassLoader ccl = caller.getClassLoader();
? ? ? ? if (ccl != null || ccl != getClass().getClassLoader()) {
? ? ? ? ? ? throw new SecurityException("You do not have permissions.");
? ? ? ? }
? ? }
});
第三,這很可能不會做你想做的。安全檢查在整個 JDK 中完成,因此調用者可能在任意數量的堆棧級別之外,需要您檢查整個堆棧(提示:在您第二次訪問堆棧中的 SecurityManager 時中斷)。
相反,定義一個策略(創建一個 java 策略文件),您可以在其中授予您的代碼所有權限并使用 java.lang.SecurityManager。
如果無法編寫您自己的策略文件,您也可以使用Policy.setPolicy()安裝您自己的java.security.Policy.
一些實現 a 的提示java.security.Policy:
覆蓋
implies
和兩種getPermissions
方法。嚴重地。趕上你自己
ProtectionDomain
的政策類。(?private static final ProtectionDomain MY_PD = MyPolicy.class.getProtectionDomain()
)如果檢查是針對您自己的 ProtectionDomain,請使用快速路徑。

TA貢獻1802條經驗 獲得超5個贊
我找到了一個臨時解決方案,但它并不完美:
System.setSecurityManager(new SecurityManager() {
public void checkPermission(Permission permission) {
Class<?> caller = SecurityManager.class;
Class<?>[] classContext = this.getClassContext();
int loopAmount = 0;
while (caller.getCanonicalName() == null
|| !caller.getCanonicalName().startsWith("nl")) {
caller = classContext[loopAmount];
loopAmount++;
}
if (caller.getClassLoader() != trustedClassLoader) {
throw new SecurityException("You do not have permissions.");
}
}
});
所有不受信任的類的規范名稱都必須以“nl”開頭。這是 afaik 從類上下文中獲取調用者類的唯一方法,因為調用者類的數組位置未知,上下文數組的最后一個元素始終是具有 main 方法的類。
添加回答
舉報