禁用当前线程的 Java 反射

我需要调用一些半可信的Java代码,并希望禁用在该代码执行期间使用反射的功能。

try{
   // disable reflection somehow
   someObject.method();
}
finally{
   // enable reflection again
}

这可以通过安全管理器来完成吗,如果是这样,如何完成?

澄清/背景:这是另一个关于限制可以从JavaScript / Rhino调用的包的问题的后续。接受的答案引用了有关如何执行此操作的博客文章,它需要两个步骤,第一个步骤使用Rhino API(ClassShutter),第二个步骤关闭反射和Class.forName()。我想我可以使用SecurityManager更干净地完成第二步(学习SecurityManager,正如已经指出的那样,这是一个复杂的野兽)。

总而言之,我希望(从代码中,而不是设置文件)关闭Class.forName()和对整个反射包的任何访问。


答案 1

这取决于您试图限制的内容。

通常,可公开访问的 API 不受限制。但是,只要您不向不可信代码授予 ReflectPermission(“suppressAccessChecks”)权限,它就无法访问另一个包中的非公共 API。

如果您有一个要限制所有访问的包列表,则有两个步骤。首先,在属性中,将受限制的包包含在 package.access 列表中。然后提供受信任的代码SecurityRuntimePermission("accessClassInPackage." + pkg)

区分不受信任的代码的常用方法是从其他位置加载它,并在授予权限时引用策略文件中的不同代码库。

Java安全架构非常强大,但我知道它也很复杂。如果你想要一个更具体的例子,请确切地描述你想要限制的调用,我会尽量更明确。


在不修改文件和/或文件的情况下做你想做的事情将非常困难,也许是不可能的。表示 中的信息,但它不提供写入访问权限。您可以创建自己的实现,并在运行时安装它,只要任何现有实现允许它。java.policyjava.securityjava.security.Policyjava.policyPolicySecurityManager

另一方面,您可以将定制 java.policy 文件指定为命令行选项。如果您要为具有某种启动器的完整应用程序提供,则可能很容易实现。它还为您的用户提供了一些透明度。经验丰富的用户可以查看您希望授予应用程序的权限。


答案 2

好吧,您可以覆盖并给出更严格的定义。但是,它实际上并不是那样工作的。例如,如果代码定义了一个收尾器,会发生什么情况?SecurityManager.checkMemberAccess

关于说明:其他 API 使用反射和其他 API。例如,java.beans,LiveConnect和Rhino。例如,对手可以在脚本中创建新的Rhino上下文,而无需快门,从而引导到完整的JRE中。使用开放的系统,黑名单永远无法完成。

总而言之:要使用Java安全模型,您需要使用它,而不是反对它。