确保经过身份验证的用户只能更新自己的记录

时间:2016-11-28 17:06:22

标签: java spring hibernate spring-security jackson

假设我有两个实体,如下所示:

@Entity
public class ClassA {
    private Long id;

    public Long getId() {
        return id;
     }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToMany
    private Set<ClassB> classBs = new HashSet<>();
}
@Entity
public class ClassB {
    private Long id;
    private String name;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

也就是说,ClassA包含一组ClassB。以及更新ClassA的资源:

@RequestMapping(method = RequestMethod.PUT)
public ClassA update(@RequestBody ClassA a){
    // Update code here
}

然后在DAO(使用hibernate)中调用以下内容来更新数据库中的ClassA:

@Override
public ClassA save(ClassA classA) {
    sessionFactory.getCurrentSession().saveOrUpdate(classA);
    return classA;
}

更新方案中,如果经过身份验证的用户将id实例的ClassB更改为属于其他用户的id,我们会发现有没有保护阻止用户更新不属于他们的对象。有什么方法可以防止这种情况吗?防止这种情况发生的最佳做法是什么(即阻止他们更新其他用户classB详细信息)?

2 个答案:

答案 0 :(得分:1)

请参阅Access Control using @PreAuthorize and @PostAuthorize

  

使用@PreAuthorize和@PostAuthorize进行访问控制

     

最明显有用的注释是@PreAuthorize,它决定了是否可以实际调用方法。例如(来自“Contacts”示例应用程序)

     
@PreAuthorize("hasRole('USER')")
public void create(Contact contact);
     

表示只允许角色为“ROLE_USER”的用户进行访问。显然,使用传统配置和所需角色的简单配置属性可以轻松实现相同的目标。但是怎么样:

     
@PreAuthorize("hasPermission(#contact, 'admin')")
public void deletePermission(Contact contact, Sid recipient, Permission permission);
     

这里我们实际上使用方法参数作为表达式的一部分来决定当前用户是否具有给定联系人的“admin”权限。内置的hasPermission()表达式通过应用程序上下文链接到Spring Security ACL模块,如下所示。您可以按名称访问任何方法参数作为表达式变量。

答案 1 :(得分:0)

这称为业务逻辑。 Hibernate没有概念id字段用于表示用户。它不会阻止您将字段设置为您想要的任何值。

调用此代码的代码,即更改ID字段,需要了解id字段的限制,并阻止用户更改它。您的UI和DAO之间应该有一个业务层来进行这种检查。