如何防止通过反射访问?
How to prevent access via reflection?
在Java文档中提到使用f.setAccessible(true)
方法我们可以违反封装原则。
但是如果我正在编写任何具有完全安全性的 class,例如使用私有变量,我如何防止它被反射访问?
例如我有一个 class 具有完全安全的实例变量:
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());
}
}
在我的代码中,如何防止不可变 class 被反射更改?
JVM 内置了安全机制,允许您通过 Java 安全策略文件定义对代码的限制。 Java 安全管理器使用 Java 安全策略文件强制执行授予 类 的一组权限。权限允许在该 JVM 实例中指定 类 运行 以允许或不允许某些运行时操作。
如果启用 Java 安全管理器但未指定安全策略文件,则 Java 安全管理器将使用在 java.security 和 java.policy 文件中定义的默认安全策略$JAVA_HOME/jre/lib/security 目录。
可以在此处找到定义策略文件 http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html
扩展 SecurityManager class 并覆盖此方法以限制反射访问
@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!");
}
}
在Java文档中提到使用f.setAccessible(true)
方法我们可以违反封装原则。
但是如果我正在编写任何具有完全安全性的 class,例如使用私有变量,我如何防止它被反射访问?
例如我有一个 class 具有完全安全的实例变量:
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());
}
}
在我的代码中,如何防止不可变 class 被反射更改?
JVM 内置了安全机制,允许您通过 Java 安全策略文件定义对代码的限制。 Java 安全管理器使用 Java 安全策略文件强制执行授予 类 的一组权限。权限允许在该 JVM 实例中指定 类 运行 以允许或不允许某些运行时操作。 如果启用 Java 安全管理器但未指定安全策略文件,则 Java 安全管理器将使用在 java.security 和 java.policy 文件中定义的默认安全策略$JAVA_HOME/jre/lib/security 目录。 可以在此处找到定义策略文件 http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html
扩展 SecurityManager class 并覆盖此方法以限制反射访问
@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!");
}
}