我需要调用一些半可靠的Java代码,并希望禁用在代码执行期间使用反射的功能。
try{
// disable reflection somehow
someObject.method();
}
finally{
// enable reflection again
}
可以使用SecurityManager完成,如果可以,怎么做?
澄清/上下文:这是another question关于限制可以从JavaScript / Rhino调用的包的后续行动。接受的答案引用了关于如何做到这一点的博客条目,它需要两个步骤,第一个使用Rhino API(ClassShutter),第二个使用关闭反射和Class.forName()。我想我可以使用SecurityManager更干净地完成第二步(了解SecurityManager,正如已经指出的那样,它是一个复杂的野兽)。
总而言之,我希望(从代码,而不是设置文件)关闭Class.forName()以及对整个反射包的任何访问。
答案 0 :(得分:18)
这取决于你想要限制的内容。
通常,可公开访问的API不受限制。但是,只要您不授予不可信赖的代码ReflectPermission("suppressAccessChecks")
权限,它就无法访问另一个包中的非公共API。
如果您有要限制所有访问权限的软件包列表,则有两个步骤。首先,在Security
属性include the restricted package in the package.access
list中。然后提供受信任的代码RuntimePermission("accessClassInPackage." + pkg)
。
区分不受信任代码的常用方法是从其他位置加载,并在授予权限时参考策略文件中的不同代码库。
Java安全架构非常强大,但我知道它也很复杂;如果你想要一个更具体的例子,请准确描述你想要限制的电话,我会更加明确。
在不修改java.policy
文件和/或java.security
文件的情况下执行您想要的操作将非常困难,也许是不可能的。 java.security.Policy
表示java.policy
中的信息,但不提供写访问权限。您可以创建自己的Policy
实现,并在运行时安装它,只要现有SecurityManager
允许它。
另一方面,您可以将自定义java.policy文件指定为命令行选项。如果您使用某种启动器提供完整的应用程序,则可能很容易实现。它还为您的用户提供了一些透明度。复杂的用户可以查看您希望授予应用程序的权限。
答案 1 :(得分:4)
好吧,你可以覆盖SecurityManager.checkMemberAccess
并给出更严格的定义。但是,它并没有真正起作用。例如,如果代码定义了终结者,会发生什么?
澄清:其他API使用反射和其他API。例如,java.beans,LiveConnect和Rhino。例如,攻击者可以在脚本中创建一个没有快门的新Rhino上下文,从而引导到完整的JRE。使用开放系统,黑名单永远无法完成。
总结:要使用Java安全模型,您需要使用它,而不是使用它。
答案 2 :(得分:1)
我写了一个ClassShutter的替代品,它允许每个实例,每个方法,每个字段进行细粒度访问控制:
http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html