xDa*_*ehh 9 java java-security java-security-manager
我有一个用于受信任的应用程序代码的ClassLoader和一个用于用户提交的(不受信任的)代码的单独的ClassLoader。
我希望安全管理器限制用户提交的代码。如何从SecurityManager中检查呼叫者的来历?参见伪代码:
System.setSecurityManager(new SecurityManager() {
public void checkPermission(Permission permission) {
if (/*caller class is not loaded by the trusted classloader*/) {
throw new SecurityException("You do not have permissions.");
}
}
});
Run Code Online (Sandbox Code Playgroud)
我已经尝试过的
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass().getClassLoader() 首先检查权限,以便给出堆栈溢出异常。
Thread.currentThread().getStackTrace()[2].getClassLoaderName() 这是不安全的,因为它仅提供类加载器名称,而不提供类对象,如果不可信加载器的规范名称与可信加载器相同,则存在安全问题。
首先,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.");
}
}
});
Run Code Online (Sandbox Code Playgroud)
其次,如果你想使用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.");
}
}
});
Run Code Online (Sandbox Code Playgroud)
第三,这很可能不会达到您想要的效果。安全检查是在整个 JDK 中完成的,因此调用者可能位于任意数量的堆栈级别之外,需要您检查整个堆栈(提示:在您第二次访问堆栈中的 SecurityManager 时中断)。
相反,定义一个策略(创建一个 java 策略文件),在其中授予代码所有权限并使用 java.lang.SecurityManager。
如果无法编写自己的策略文件,您还可以使用Policy.setPolicy()安装自己的java.security.Policy.
实施的一些提示java.security.Policy:
implies这两种getPermissions方法。严重地。ProtectionDomain的策略课程。( private static final ProtectionDomain MY_PD = MyPolicy.class.getProtectionDomain())| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |