如何在Java中找到调用方法的对象
我能找到在Java中调用方法的对象吗?我与团体和个人有一个社交网络。如果一个人想要离开一个组,只有这样才能将自己从组中移除,其他人无法移除该人,不知何故,调用该方法的人必须证明其身份。您可以通过分析堆栈跟踪(如本问题中所述:)通过反射来实现这一点如何在Java中找到调用方法的对象,java,authentication,Java,Authentication,我能找到在Java中调用方法的对象吗?我与团体和个人有一个社交网络。如果一个人想要离开一个组,只有这样才能将自己从组中移除,其他人无法移除该人,不知何故,调用该方法的人必须证明其身份。您可以通过分析堆栈跟踪(如本问题中所述:)通过反射来实现这一点 然而,在大多数情况下,这将是对反思的滥用。你应该仔细考虑你的方法有一个额外的参数叫做“代码>调用器< /代码>(调用方应该用这个< /代码>填充)。 < p> Oli的解决方案的风险是恶意代码可以调用“移除”方法并指定一个不同的调用对象。 如果您使用的
然而,在大多数情况下,这将是对反思的滥用。你应该仔细考虑你的方法有一个额外的参数叫做“代码>调用器< /代码>(调用方应该用<代码>这个< /代码>填充)。 < p> Oli的解决方案的风险是恶意代码可以调用“移除”方法并指定一个不同的调用对象。
如果您使用的是Spring security之类的安全框架,您可以请求当前主体,只允许从组中删除该用户,或者如果该用户是管理员,则允许从组中删除任何用户。检查方法的调用方是经验不足的程序员的常见请求。我感到惊讶的是,它并没有出现在如此频繁。但这是一个非常糟糕的想法(只需查看Java2(或者更早更糟糕的)安全模型) 在少数情况下,实施此限制非常重要。正如奥利·查尔斯沃思所说,不要这样做。但让我们假设这很重要,但我们不打算进行堆栈检查 让我们先假设我们信任团队。一种有效但无意义的方法是向团队传递一个只有个人才能创建的代表个人的对象。(注意Java语言访问限制是基于类的。不同的实例可以创建这样的代理,但代码必须在
Person
类中。)
如果我们不信任该小组,那么我们可以扩大代理范围以引用该小组。这可以防止恶意组从其他组注销某人
public class Group { // Can have malicious subclasses.
public void deregisterPerson(Person.GroupDeregister deregister) {
if (deregister.group() != this) { // Not equals...
throw new IllegalArgumentException();
}
Person person = deregister.person();
...
}
}
public class Person { // May be subclassed.
public final class GroupDeregister {
private final Group group;
private GroupDeregister(Group group) { // Hidden.
this.group = group;
}
public Person person() {
return Person.this;
}
public Group group() {
return group;
}
}
private void groupDeregister(Group group) {
group.deregisterPerson(new GroupDeregister(group));
}
}
另一种方法是制作一个“公开”版本的人,可以暴露给其他人
public class Person { // "PrivatePerson"
public PublicPerson publicPerson() {
return new PublicPerson(this);
}
private void groupRegister(Group group) {
group.registerPerson(this);
}
private void groupDeregister(Group group) {
group.deregisterPerson(this);
}
...
}
public class PublicPerson {
private final Person person;
public PublicPerson(Person person) {
this.person = person;
}
@Override public final boolean equals(Object obj) {
return obj instanceof Person && (Person)obj.person == person;
}
@Override public final int hashCode() {
return person.hashCode();
}
...methods, but no raw registration...
}
public class Group {
private final Set<Person> members = new IdentityHashSet<>(); // No Object.equals.
public void registerPerson(Person person) {
members.add(person);
}
public void deregisterPerson(Person person) {
members.remove(person);
}
public Set<PublicPerson> members() {
// This will be more concise in Java SE 8.
Set<PublicPerson> publics = new HashSet<>();
for (Member member : members) {
publics.add(member.publicPerson());
}
return unmodifiableSet(publics);
}
}
public-class-Person{//“PrivatePerson”
公众人士公众人士(){
返回新的公众人物(本);
}
私有无效组寄存器(组){
集团注册人(本);
}
私有无效组注销器(组){
集团注销人(本);
}
...
}
公共类公众人物{
私人最终人;
公众人士{
这个人=人;
}
@覆盖公共最终布尔等于(对象obj){
返回Person的obj实例&&(Person)obj.Person==Person;
}
@重写公共final int hashCode(){
return person.hashCode();
}
…方法,但没有原始注册。。。
}
公共课组{
private final Set members=new IdentityHashSet();//无Object.equals。
公共无效登记人(人){
成员。增加(人);
}
公共作废注销人(人){
成员。免职(人);
}
公共集成员(){
//在JavaSE8中,这将更加简洁。
Set publics=new HashSet();
代表(成员:成员){
publics.add(member.publicPerson());
}
返回不可修改集(publics);
}
}
(
Objects.requirennoull
为“简洁”而省略)只需将“this”传递给该方法,但除非您计划让其他人调用您的代码,否则我不明白您为什么担心安全性。只是不要编写任何允许A从C中删除B的代码,或者确实允许A获取对B的引用的代码。是的,但是如果我想从该组的朋友列表中删除一个朋友,我可以这样调用该方法:group.removeFriend(myFriend,myFriend//这就是调用方)。只有组管理员才能删除成员。@JohnSmith:如果您确实担心这种情况,请向Person
(或任何基类)添加protectedfinal
helper方法,它负责正确调用group.removeFriend
方法。该链接不相关:它找到的是调用方类,而不是对象。它找不到调用对象的类。它将找到在其中定义调用此方法的方法的类。如果你想找到一个抽象类的具体实现,这不一定会有帮助。@dhasenan-我不太明白。如果目标是确定直接/直接调用方,那么让该调用方传入this
应该有效这只是允许执行任意代码时的问题。这听起来不是一个好主意……关于编写代码,你可以保证的一件事是,有一天其他人会维护它,他们会用它做一些愚蠢的事情。当然,但这永远是真的。你不能防止任意的愚蠢行为!虽然我同意设计一个API的原则,这样就很难不正确地使用它,但添加一个完整的安全机制仅仅是为了防止有人假设地将错误的参数传递给一个方法,这对我来说似乎太过分了。我觉得从OP中可以安全地假设用户必须登录这个系统(至少是为了识别自己)。要求是阻止用户删除其他人。此解决方案保证了这一点,并减少了出现错误的可能性。
public class Person { // "PrivatePerson"
public PublicPerson publicPerson() {
return new PublicPerson(this);
}
private void groupRegister(Group group) {
group.registerPerson(this);
}
private void groupDeregister(Group group) {
group.deregisterPerson(this);
}
...
}
public class PublicPerson {
private final Person person;
public PublicPerson(Person person) {
this.person = person;
}
@Override public final boolean equals(Object obj) {
return obj instanceof Person && (Person)obj.person == person;
}
@Override public final int hashCode() {
return person.hashCode();
}
...methods, but no raw registration...
}
public class Group {
private final Set<Person> members = new IdentityHashSet<>(); // No Object.equals.
public void registerPerson(Person person) {
members.add(person);
}
public void deregisterPerson(Person person) {
members.remove(person);
}
public Set<PublicPerson> members() {
// This will be more concise in Java SE 8.
Set<PublicPerson> publics = new HashSet<>();
for (Member member : members) {
publics.add(member.publicPerson());
}
return unmodifiableSet(publics);
}
}