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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7566626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:32:28  来源:igfitidea点击:

How to restrict developers to use reflection to access private methods and constructors in Java?

javasecurityreflection

提问by Satya

How to restrict developers to use reflection to access private methods and constructors in Java?

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

Using normal Java code we can't access private constructors or private methods outside of a class. But by using reflection we can access any private methods and constructors in a Java class.

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

So how can we give security to our Java code?

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

采纳答案by Joachim Sauer

Run your application using a SecurityManagerand a sufficiently restrictive security policy.

使用SecurityManager和 足够严格的安全策略运行您的应用程序。

There's a short summary in the tutorialand extensive information in the security documentation.

教程中简短摘要,安全文档中有大量信息。

回答by swanliu

Add checkPermission()method in all of your private method/constructor. checkPermission using sun.reflect.Reflection.getCallerClass(int n)by assert callerClass=selfClass.

checkPermission()在所有私有方法/构造函数中添加方法。 checkPermission 使用sun.reflect.Reflection.getCallerClass(int n)by assert callerClass=selfClass

The getCallerClassreturns the class of the method realFramesToSkipframes up the stack (zero-based), ignoring frames associated with java.lang.reflect.Method.invoke()and its implementation. The first frame is that associated with this method, so getCallerClass(0)returns the Class object for sun.reflect.Reflection.

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

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();
        }
    }
}

You can try to test reflect, it will fail:

您可以尝试测试反射,它会失败:

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();
    }
} 

回答by Thilo

You (as the developer of the code in question) cannot do that.

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

The end user, who runs the application, could install a SecurityManager that forbids reflection.

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