gpt4 book ai didi

java - 只允许从某些包构建对象

转载 作者:行者123 更新时间:2023-11-30 11:32:16 25 4
gpt4 key购买 nike

我在一个类似游戏的系统上工作。用户可以提交 .class 和 .java 文件来定制行为。有些对象是通过回调传递给用户的,但是如果用户可以自己构造这些对象(使用自定义参数),这对他来说意味着一个优势。我将禁止用户反射(reflect)并密封我的包裹。如果我放弃所有包结构(并使构造函数包私有(private)),我可以让它工作,但我不想这样做。


这是一个例子:

sscce.mycode.a.SomeClass.java:

package sscce.mycode.a;

import sscce.mycode.b.RestrictedObject;
import sscce.usercode.SomeUserClass;

public class SomeClass {

public static void main(String[] args) {
SomeUserClass userClass=new SomeUserClass();

// If I can create it from here, anyone can...
RestrictedObject object=new RestrictedObject();

userClass.someMethod(object);
}

}

sscce.mycode.b.Interface.java:

package sscce.mycode.b;

public interface Interface {

public void someMethod(RestrictedObject restrictedObject);

}

sscce.mycode.b.RestrictedObject.java:

package sscce.mycode.b;

public class RestrictedObject {

public RestrictedObject() {}

}

sscce.usercode.SomeUserClass.java:

package sscce.usercode;

import sscce.mycode.b.Interface;
import sscce.mycode.b.RestrictedObject;

public class SomeUserClass implements Interface {

@Override
public void someMethod(RestrictedObject restrictedObject) {
// It receives an instance, but cannot create it.
System.out.println("Got "+restrictedObject);
}
}

动机:把所有东西都放在一个包里听起来很乱……

有没有人知道如何在不压扁包的情况下实现这一点?
提前感谢任何解决方案、想法或意见,直到

最佳答案

您可以通过以下方式进行,但是如果您真的想使用这种方法,您应该仔细考虑,因为它非常缓慢,坦率地说,这是一种不好的做法。无论如何,我都会提出您可以如何做到这一点:

public final class Secured {

private static final Set<Class<?>> allowedCallers = new HashSet<>();

static {
allowedCallers.add(Allowed.class);
}

private static final class SecurityManagerExtension extends SecurityManager {

private static final int OFFSET = 4;

@Override
protected Class<?>[] getClassContext() {
return super.getClassContext();
}

private Class<?> getCaller() {
try {
return getClassContext()[OFFSET];
} catch (ArrayIndexOutOfBoundsException e) {
return null;
}
}
}

private Secured() {
// protect against reflection attack
Class<?> caller = new SecurityManagerExtension().getCaller();
if (!this.getClass().equals(caller)) {
throw new IllegalStateException();
}
System.out.println("Secured instance constructed!");
}

public static Secured createInstance() {
// this gets the class name of the calling class
Class<?> caller = new SecurityManagerExtension().getCaller();
if (allowedCallers.contains(caller)) {
System.out.println("Created instance by '" + caller + "'!");
return new Secured();
} else {
System.out.println("No instance created because call was made by '" + caller + "'!");
return null;
}
}
}

注意类上的 final 关键字以防止子类化。如果您需要自己对类进行子类化,请将 final 关键字移至工厂方法。另请注意,这不能防止序列化攻击。

关于java - 只允许从某些包构建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16751607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com