Java - 如何限制特定方法的方法调用

Wri*_*juB 3 java methods restrict

我有一个特殊的要求,我需要确保只允许一个类中的特定方法从第二个类调用公共(非静态)方法.不能使用继承.

一种选择是使用StackTrace,如下所示:

ClassA.java

package org.rnd.stack;


public class ClassA {
    public void methodA() throws IllegalAccessException {
        Exception fake = new Exception("FAKE-IGNORE");
        StackTraceElement[] stack = fake.getStackTrace();
        StackTraceElement st = stack[1];
        if ("org.rnd.stack.ClassB".equals(st.getClassName())
                && "methodB".equals(st.getMethodName())) {
            System.out.println("You are allowed to call");
        } else {
            throw new IllegalAccessException("You are not allowed to call");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ClassB.java

package org.rnd.stack;

public class ClassB {
    public void methodB() throws IllegalAccessException {
        new ClassA().methodA();
    }

    public void illegalMethod() throws IllegalAccessException {
        new ClassA().methodA();
    }

    public static void main(String[] args) {
        try {
            new ClassB().methodB();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在上述解决方案工作正常,但由于代码审计中的质量控制,我需要提出另一个(或更确切地说)更好的解决方案.有没有更好的方法来实现这一目标?

dim*_*414 7

正确的做法是重新审视您的要求.只能由某些其他代码路径调用的方法与此不兼容public.一般的最佳做法是使用package-private来阻止外部调用者,并接受包中的任何代码都可以调用该方法,但不会因为您或您的团队正在审核它.

方法可见性最终不是防止执行的安全解决方案; 有人拥有你的.class文件并能够在机器上执行它们,他们可以做任何他们想要的事情.你不应该花太多时间试图锁定方法调用.相反,要清楚地记录方法的意图(例如" 帮助函数methodB(),请不要在别处使用. ")并相信与你一起开发的人知道他们在做什么.你甚至可以给这个方法一个清晰的名字,就好像dangerousMethodBForInternalUseOnly()你真的想要打败人们一样.

您可能还对依赖注入感兴趣,这是一种使用类型系统来保护(不阻止)人们执行危险代码的设计模式.这里有一些关于Guice的讨论,Guice是一个流行的DI框架,它详细介绍了这个概念:


所有这些都说,作为一种学术练习,这里是将方法调用限制为固定数量的代码路径的一种选择 - 依赖于共享秘密.Object secret向锁定方法添加一个字段,如果传递的内容secret与硬编码值(private static final Object SECRET = new Object())不匹配,则导致方法失败.然后,您可以使用其他机制仅将密码共享给您允许的代码路径(例如,在锁定类中使用静态初始化程序将其发布到您明确信任的类中).

显然,这仍然可以被恶意开发人员解决,而且非常严重,但它会提供某种锁定行为,假设您可以相信您的锁定类不会在您不知情的情况下更改.