反思安全
如何通过不允许Method
, Field
, Constructor
对象调用setAccessible(true)
来强制执行reflection安全性? SecurityPolicy文件还是其他什么?
通常,对于独立Java应用程序,没有注册SecurityManager
。
我使用这个System.setSecurityManager(new SecurityManager());
这种方法适用于调用方法。
我想强制执行使用jar的整个jar或客户端代码不允许调用setAccessible(true);
有更好的方法吗?
谢谢。
嗯,它确实适用于setAccessible。 看到:
class A { private String method1() { return "Hello World!"; } }
和
import java.lang.reflect.Method; class B { public static void main(String[] args) throws Exception { System.setSecurityManager(new SecurityManager()); Class clazz = A.class; Method m = clazz.getDeclaredMethod("method1"); m.setAccessible(true); } }
结果是
Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks") at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.reflect.AccessibleObject.setAccessible(Unknown Source) at B.main(B.java:8)
它可能对你不起作用的一个原因是,根据这篇文章中的评论,它不能用于Java 1.5,但在6及其后工作。
编辑:要为特定的jar子拒绝它,您需要使用策略文件,例如:
// specific file grant codeBase "file:/test/path/tools.jar" { // no permissions for this one }; // default to giving all grant { permission java.security.AllPermission; };
有两种方法可以指定策略文件,或者将其作为默认值添加,或者仅提供指定的( 源 ):
如果你使用
java -Djava.security.manager -Djava.security.policy==someURL SomeApp
(注意双等号)然后只使用指定的策略文件; 安全属性文件中指示的所有内容都将被忽略。
…或者实现一个看起来不那么难的自定义安全管理器。 虽然我自己没有这样做。