如何限制某些用户使用 PUT 和 Spring Data Rest 编辑对象的所有属性?

How to restrict certain users from editing all attributes of an object using PUT with Spring Data Rest?

当使用 Spring Data Rest 时,有没有办法让某些用户使用 PUT 请求只编辑实体的一部分?

以此项为例:

{
    "name": "Item1",
    "description": "Description",
    "creator": "User1"
}

让项目的创建者使用 PUT 请求编辑整个项目同时限制其他用户只能编辑 "description" 字段的最佳方法是什么?

我试过使用自定义验证器和事件处理程序,但没有成功。

我认为自定义 Validator 是您的正确选择。

首先 - 更新您的实体以使其保存之前的状态(感谢 @AlanHay):

@Entity
class ItemEntity {

    @Transient
    private ItemEntity previousState;

    @PostLoad
    private void setPreviousState(){
        previousState = new ItemEntity();
        //copy the fields
    }

    public ItemEntity getPreviousState(){
        return previousState;
    }
} 

然后实现验证器,在其中检查当前用户 'authority' 是否更改了字段:

public class ItemValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {   
        //...
    }

    @Override
    public void validate(Object target, Errors errors) {

        Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        SimpleGrantedAuthority userRole = new SimpleGrantedAuthority("ROLE_USER");

        if (authorities.contains(userRole)) {

            ItemEntity item = (ItemEntity) target;
            prevItem = item.getPreviousState();

            String prevName = prevItem.getName();
            String prevCreator = prevItem.getCreator();
            String newName = item.getName();
            String newCreator = item.getCreator();

            if (!prevName.equals(newName)) {
                errors.rejectValue("name", "You cannot change Name field!");
            }

            if (!prevCreator.equals(newCreator)) {
                errors.rejectValue("creator", "You cannot change Creator field!");
            }
        }
        // Other checks...
    }
}

然后在 RepositoryRestConfigurerAdapter 中插入这个验证器:

@Configuration
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
        v.addValidator("beforeCreate", itemValidator()); // POST (if needed)
        v.addValidator("beforeSave", itemValidator());   // PUT/PATCH
        super.configureValidatingRepositoryEventListener(v);
    }

    @Bean
    ListingValidator itemValidator() {
        return new ItemValidator();
    }
} 

我认为这应该可行...