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 方法的类。
添加回答
举报