如何防止通过反射进入?

2022-09-04 19:51:50

在Java文档中,它提到使用方法我们可以违反封装的原则。f.setAccessible(true)

但是,如果我正在编写任何具有完全安全性的类,例如使用私有变量,我该如何防止通过反射访问它?

例如,我有一个具有完整安全实例变量的类:

public final class Immutable {
    private final int someVal;

    public Immutable(int someVal) {
        this.someVal = someVal;
    }

    public int getVal() {
        return someVal;
    }
}

但是我可以使用反射来修改该实例变量,如下所示:

public class Tester {
    public static void main(String[] args)
            throws NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {

        Immutable i = new Immutable(10);

        // output 10
        System.out.println(i.getVal());

        Field f = i.getClass().getDeclaredField("someVal");
        f.setAccessible(true);
        f.set(i, 11);

        // output is 11 which implies some value modified
        System.out.println(i.getVal());
    }
}

在我的代码中,如何防止不可变类被反射更改?


答案 1

JVM 内置了安全机制,允许您通过 Java 安全策略文件定义对代码的限制。Java 安全管理器使用 Java 安全策略文件强制实施授予类的一组权限。这些权限允许在 JVM 的该实例中运行的指定类允许或不允许某些运行时操作。如果启用了 Java 安全管理器,但未指定安全策略文件,那么 Java 安全管理器将使用在 $JAVA_HOME/jre/lib/security 目录中的 java.security 和 java.policy 文件中定义的缺省安全策略。可以在此处找到定义策略文件 http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html


答案 2

扩展 SecurityManager 类并重写此方法以限制反射访问

@Override
public void checkPackageAccess(String pkg){

         // don't allow the use of the reflection package
         if(pkg.equals("java.lang.reflect")){
             throw new SecurityException("Reflection is not allowed!");
         }
     }