如何限制开发人员使用反射访问Java中的私有方法和构造函数?

Posted

技术标签:

【中文标题】如何限制开发人员使用反射访问Java中的私有方法和构造函数?【英文标题】:How to restrict developers to use reflection to access private methods and constructors in Java? 【发布时间】:2011-11-25 20:50:00 【问题描述】:

如何限制开发者使用反射访问Java中的私有方法和构造函数?

使用普通的 Java 代码,我们无法访问类之外的私有构造函数或私有方法。但是通过使用反射,我们可以访问 Java 类中的任何私有方法和构造函数。

那么我们怎样才能为我们的 Java 代码提供安全性呢?

【问题讨论】:

这对于签名的 jar 来说是一个不错的选择。 “在任何情况下,都不允许对此 jar 文件中的类进行反射”。但我认为,没有这样的功能。 【参考方案1】:

使用SecurityManager 和足够严格的security policy 运行您的应用程序。

short summary in the tutorial 有一个the security documentation 和大量信息。

【讨论】:

【参考方案2】:

在所有私有方法/构造函数中添加 checkPermission() 方法。 通过断言callerClass=selfClass 使用sun.reflect.Reflection.getCallerClass(int n) 检查权限。

getCallerClass 返回方法 realFramesToSkip 的类在堆栈中向上帧(从零开始),忽略与 java.lang.reflect.Method.invoke() 及其实现相关的帧。第一帧是与此方法关联的帧,因此getCallerClass(0) 返回sun.reflect.Reflection 的Class 对象。

public class PrivateConstructorClass 

    private PrivateConstructorClass() 
        checkPerMission();
              //you own code go below
    

    void checkPerMission() 
        Class self = sun.reflect.Reflection.getCallerClass(1);
        Class caller = sun.reflect.Reflection.getCallerClass(3);
        if (self != caller) 
            throw new java.lang.IllegalAccessError();
        
    

你可以试试reflect,会失败:

public class TestPrivateMain 

    Object newInstance() throws Exception 

        final Class<?> c = Class.forName("package.TestPrivate");

        final Constructor<?> constructor = c.getDeclaredConstructor();
        constructor.setAccessible(true);
        return constructor.newInstance();

    

    public static void main(String[] args) throws Exception 
        Object t = new TestPrivateMain().newInstance();
    
 

【讨论】:

嗯...但在我看来确实是一个很好的尝试。不稳定的 API 一开始就不应该存在【参考方案3】:

您(作为相关代码的开发者)不能这样做。

运行应用程序的最终用户可以安装一个禁止反射的 SecurityManager。

【讨论】:

他当然可以。他在应用程序启动期间安装了安全管理器。 除非他是应用程序的开发者,否则这不是一个选项。我更多地考虑了他“希望限制开发人员 [可能是应用程序的] 使用反射”来反对他希望保持私有的方法的情况。 是什么阻止他在他的类中使用静态初始化程序来安装安全管理器?并且ofc会抛出一个异常,防止class laoding,如果他不能安装呢?

以上是关于如何限制开发人员使用反射访问Java中的私有方法和构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

07 JVM 是如何实现反射的

java反射访问私有方法的的问题

如何通过反射访问私有方法和私有数据成员?

C# - 快速观察中的“可读”内部属性​​但不使用反射?

java里一个私有的属性如何在其他类里面进行访问?

为啥 Java 反射 API 允许我们访问私有和受保护的字段和方法?这不会破坏访问修饰符的目的吗? [复制]